web-dev-qa-db-ja.com

Django ManyToManyカウントでモデルをフィルタリングしますか?

私の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")

次に、views.pyで、0を超える参加者がいるユーザーのパーティーをフェッチするクエリを実行します。

このような何か多分:

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

それを行う最良の方法は何ですか?

65
Ska

これが機能する場合、これは私がやる方法です。

最良の方法は多くのことを意味します:最高のパフォーマンス、最も維持しやすいなどです。したがって、これが最良の方法であるとは言いませんが、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))
107
solartic
Party.objects.filter(organizer=user, participants__isnull=False)
Party.objects.filter(organizer=user, participants=None)
31

excludeでより簡単:

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

また、異なる結果を返します

5

@ Yuji-'Tomita'-Tomitaの回答から派生し、重複したレコードを除外するために.distinct( 'id')も追加しました。

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

したがって、各当事者は一度だけリストされます。

1
Kostyantyn