Let's say I have the following models:
class Poll(model):
title = models.CharField()
class Option(model):
title = models.CharField()
polls = models.ManyToManyField(
Poll,
through='PollOption',
null=True,
blank=True,
related_name='options'
)
class PollOptionManager(models.Manager):
use_for_related_fields = True
def get_queryset(self):
return super(PollOptionManager, self).get_queryset().filter(
is_active=True
)
class PollOption(model):
poll = ForeignKey(Poll)
option = ForeignKey(Option)
is_active = BooleanField(default=True)
objects = PollOptionManager()
When I try to query Poll.options.all()
I'm still getting Option
instances for which PollOption.is_active
is False
. How can I get my model manager to appropriately filter my ManyToMany
relationship based on a flag on the through
field?
The problem is that the through model's (related) manager is never actually used in your scenario. In order to utilize the custom manager, you have to explicitly use it, e.g.:
class Poll(models.Model):
@property
def active_options(self):
return Option.objects.filter(id__in=self.polloption_set.values_list('option'))
Here, polloption_set
filters out inactive options as intended. This, however, makes the manager kind of pointless because you can just as well put the extra filter in the custom property.