Подтвердить что ты не робот

Пользовательский менеджер 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, или я делаю что-то неправильно?

4b9b3361

Ответ 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().