Alexander Fedotov
Alexander Fedotov

Reputation: 1075

Django - query filter on manytomany is exists

I have such a model:

class News(models.Model):
    # ...
    channels = models.ManyToManyField(Channel)
    # ...

What is the most effective way to fetch news related to channels?

Upvotes: 6

Views: 6170

Answers (2)

Jura Brazdil
Jura Brazdil

Reputation: 1100

This is more complicated than it seems. I have a model Step with an ingredients m2m field. Only 603 is correct :)

>>> Step.objects.count()
735
>>> Step.objects.filter(ingredients=True).count()
159
>>> Step.objects.exclude(ingredients=False).count()
735
>>> Step.objects.exclude(ingredients=None).count()
603
>>> Step.objects.filter(ingredients__isnull=False).distinct().count()
603
>>> Step.objects.filter(ingredients__isnull=False).count()
59310
>>> sum([step.ingredients.exists() for step in Step.objects.all()])
603

Upvotes: 4

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476813

For a given channel, you can filter with:

News.object.filter(channels=my_channel)

for a collection (list, QuerySet, ...):

News.object.filter(channels__in=my_channel_collection)

For News objects that have at least one (or more) channels, we can query with:

News.objects.filter(channels__isnull=False).distinct()

or with .exclude(..):

News.objects.exclude(channels=None)

Upvotes: 11

Related Questions