Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django filter the model on ManyToMany count?

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?

like image 408
Ska Avatar asked Oct 25 '11 02:10

Ska


People also ask

How do you count to many fields in Django?

We retrieve all of the objects from the ManyToManyField, products, using the line, shoppingcartitems= shoppingcartuser. products. all() If we add, . count(), to the end of this, we are able to get the count of all of the objects in the ManyToManyField.

How can I filter a Django query with a list of values?

To filter a Python Django query with a list of values, we can use the filter method with in . to search Blog entries with pk set to 1,4 or 7 by calling Blog. objects. filter with the pk_in argument set to [1, 4, 7] .

How do I filter records in Django?

The filter() method is used to filter you search, and allows you to return only the rows that matches the search term.

Can you filter by property Django?

Nope. Django filters operate at the database level, generating SQL. To filter based on Python properties, you have to load the object into Python to evaluate the property--and at that point, you've already done all the work to load it.


3 Answers

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))
like image 65
solartic Avatar answered Oct 08 '22 16:10

solartic


Party.objects.filter(organizer=user, participants__isnull=False)
Party.objects.filter(organizer=user, participants=None)
like image 38
Yuji 'Tomita' Tomita Avatar answered Oct 08 '22 15:10

Yuji 'Tomita' Tomita


Easier with exclude:

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

Also returns distinct results

like image 6
Arseniy Panfilov Avatar answered Oct 08 '22 15:10

Arseniy Panfilov