Django での Q オブジェクトの否定に関して、非常に奇妙な問題が発生しています。例としてサッカーを使用しましょう。
class Team(models.Model):
id = UUIDField(primary_key=True)
class Player(models.Model):
id = UUIDField(primary_key=True)
name = models.CharField(max_length=128)
team = models.ForeignKey(Team)
touchdowns = models.IntegerField()
10チームあります。
プレイヤーは 100 人で、各チームには 10 人が所属しています。各チームには「ジョー」という名前のプレーヤーがいます。5回のタッチダウンを記録した1つのチームに1人の「ジョー」がいます。他のすべてのジョーは 1 回のタッチダウンを記録しています。すべてのプレーヤーが 1 回のタッチダウンしか記録していないチームが 8 つあります。
少なくとも 3 回のタッチダウンを記録した Joe という名前のプレーヤーがいるチームを取得したいと考えています。
models.Team.objects.filter(Q(player__name="Joe", player__touchdowns__gte=3)).count()
これは当然のことながら 1 を返します。それを否定すると 9 が返されます (少なくとも 3 回のタッチダウンを行った Joe という名前のプレーヤーがいない他の 9 チーム):
models.Team.objects.filter(~Q(player__name="Joe", player__touchdowns__gte=3)).count()
代わりに、そのチームの全員が 3 タッチダウン (8) 未満のチームを返します。
どこが間違っていますか?これの実際の適用ははるかに複雑であるため、Q オブジェクトを否定と共に使用する必要があることに注意してください。Exclude は使用できません。