Django filter the model on ManyToMany count?

DjangoDjango ModelsDjango Queryset

Django Problem Overview


Suppose I have something like this in my models.py:

class Hipster(models.Model):
  name = CharField(max_length=50)

class Party(models.Model):
  organiser = models.ForeignKey()
  participants = models.ManyToManyField(Profile, related_name="participants")

Now in my views.py I would like to do a query which would fetch a party for the user where there are more than 0 participants.

Something like this maybe:

user = Hipster.get(pk=1) 
hip_parties = Party.objects.filter(organiser=user, len(participants) > 0)

What's the best way of doing it?

Django Solutions


Solution 1 - Django

If this works this is how I would do it.

Best way can mean a lot of things: best performance, most maintainable, etc. Therefore I will not say this is the best way, but I like to stick to the ORM features as much as possible since it seems more maintainable.

from django.db.models import Count

user = Hipster.objects.get(pk=1) 
hip_parties = (Party.objects.annotate(num_participants=Count('participants'))
                            .filter(organiser=user, num_participants__gt=0))

Solution 2 - Django

Party.objects.filter(organizer=user, participants__isnull=False)
Party.objects.filter(organizer=user, participants=None)

Solution 3 - Django

Easier with exclude:

# organized by user and has more than 0 participants
Party.objects.filter(organizer=user).exclude(participants=None)

Also returns distinct results

Solution 4 - Django

Derived from @Yuji-'Tomita'-Tomita answer, I've also added .distinct('id') to exclude the duplitate records:

Party.objects.filter(organizer=user, participants__isnull=False).distinct('id')

Therefore, each party is listed only once.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSkaView Question on Stackoverflow
Solution 1 - DjangosolarticView Answer on Stackoverflow
Solution 2 - DjangoYuji 'Tomita' TomitaView Answer on Stackoverflow
Solution 3 - DjangoArseniy PanfilovView Answer on Stackoverflow
Solution 4 - DjangoKostyantynView Answer on Stackoverflow