76 votes

Django filtre le modèle sur le nombre ManyToMany ?

Supposons que j'ai quelque chose comme ça dans mon 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")

Maintenant, dans mon views.py, je voudrais faire une requête qui récupérerait une fête pour l'utilisateur où il y a plus de 0 participants.

Quelque chose comme ça peut-être :

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

Quelle est la meilleure façon de le faire?

127voto

solartic Points 1796

Si ça marche, c'est comme ça que je le ferais.

Le meilleur moyen peut signifier beaucoup de choses : les meilleures performances, le plus maintenable, etc. Par conséquent, je ne dirai pas que c'est le meilleur moyen, mais j'aime autant que possible m'en tenir aux fonctionnalités ORM car elles semblent plus faciles à maintenir.

 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))

33voto

Yuji 'Tomita' Tomita Points 46106
Party.objects.filter(organizer=user, participants__isnull=False)
Party.objects.filter(organizer=user, participants=None)

6voto

Arseniy Panfilov Points 151

Plus facile avec exclude :

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

Renvoie également des résultats distincts

4voto

Kostyantyn Points 661

Dérivé de la réponse @Yuji-'Tomita'-Tomita, j'ai également ajouté .distinct('id') pour exclure les enregistrements en double :

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

Par conséquent, chaque partie n'est répertoriée qu'une seule fois.

0voto

Andrew G Points 241

Peut-être mieux sera de stocker les participants de quantité dans un champ supplémentaire, car pour 100 éléments, il y aura 100 requêtes SQL.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X