Django фильтрует модель по счету ManyToMany? - PullRequest
58 голосов
/ 25 октября 2011

Предположим, что у меня есть что-то подобное в моих моделях.py:

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

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

Теперь в моем views.py я хотел бы сделать запрос, который выбрал бы вечеринку для пользователя, где более 0 участников.

Примерно так:

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

Какой лучший способ сделать это?

Ответы [ 4 ]

107 голосов
/ 25 октября 2011

Если это сработает, я так и сделаю.

Лучший способ может означать много вещей: лучшую производительность, удобство обслуживания и т. Д. Поэтому я не буду говорить, что это лучший способ, но янравится как можно больше придерживаться функций ORM, так как они кажутся более удобными в обслуживании.

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))
31 голосов
/ 25 октября 2011
Party.objects.filter(organizer=user, participants__isnull=False)
Party.objects.filter(organizer=user, participants=None)
5 голосов
/ 08 июля 2016

Проще с exclude:

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

Также возвращает отличные результаты

1 голос
/ 31 декабря 2017

Полученный из ответа @ Yuji-'Tomita-Tomita, я также добавил .distinct ('id'), чтобы исключить дублирующиеся записи:

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

Поэтому каждая партия указана только один раз.

...