Пользовательский менеджер Django с ManyToManyField
У меня есть модель с ManyToManyField с сквозной моделью, в которой есть логическое поле, которое я бы хотел отфильтровать.
from simulations.models import *
class DispatcherManager(models.Manager):
use_for_related_fields = True
def completed(self):
original = super(DispatcherManager,self).get_query_set()
return original.filter(dispatchedsimulation__status=True)
def queued(self):
original = super(DispatcherManager,self).get_query_set()
return original.filter(dispatchedsimulation__status=False)
class Dispatcher(models.Model):
name = models.CharField(max_length=64)
simulations = models.ManyToManyField('simulations.Simulation',
through='DispatchedSimulation')
objects = DispatcherManager()
class DispatchedSimulation(models.Model):
dispatcher = models.ForeignKey('Dispatcher')
simulation = models.ForeignKey('simulations.Simulation')
status = models.BooleanField()
Я думал, что переменная use_for_related_fields
позволит мне фильтровать результаты m2m как на диспетчере d так: d.simulations.completed()
или d.simulations.queued()
, но они не работают так, как я ожидал. Я не понимаю, как работает use_for_related_fields
, или я делаю что-то неправильно?
Ответы
Ответ 1
В документах Использование менеджеров для доступа к связанным объектам:
вы можете заставить Django использовать тот же класс, что и менеджер по умолчанию для вашей модели, установив атрибут use_for_related_fields в классе менеджера.
Значение, в вашем случае, вы можете заставить d.simulation
использовать обычный SimulationManager (а не DispatcherManager - DispatcherManager будет использоваться для противоположного направления ссылки. Например, Simulation.objects.get(id=1).dispatcher_set.completed
).
Я думаю, что самый простой способ добиться того, что вы хотите, - определить методы get_completed_simulations
и get_queued_simulations
в DispatcherManager. Таким образом, использование будет d.get_completed_simulations()
.