多个子集容器的Django查询

2024-10-06 16:25:11 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有一种方法可以查询包含多对多字段的子集或超集?在

假设每个人都有一个他们想看的鸟的列表,每个鸟舍都有一个鸟类列表。对于一个给定的Person实例,我如何进行查询以查找哪些鸟类在Person的列表中都有每只鸟?同样地,对于一个给定的人的例子,我如何找出哪些鸟类在这个人的列表中只有鸟(但不一定是所有的鸟)。在

以下是我的Django 1.5车型:

class Bird(models.Model):
    name = models.CharField(max_length=255, unique=True)

class Aviary(models.Model):
    name = models.CharField(max_length=255, unique=True)
    birds = models.ManyToManyField(Bird)

class Person(models.Model):
    name = models.CharField(max_length=255, unique=True)
    birds_to_see = models.ManyToManyField(Bird)

我知道怎样才能找到至少拥有一只人类鸟类的鸟类的鸟类,但我不知道我将如何适应这里。(例如,参见: django queryset for many-to-many field

如果有一个查询可以满足我的需要,我也很想知道是否/为什么这样做比“手动”更可取。例如,我可以循环遍历鸟舍,提取每个鸟舍的鸟类列表,并查看此人的“鸟雀”是否是鸟舍鸟类列表的子集或超集:

^{pr2}$

感谢任何帮助!在


Tags: nametrue列表model鸟类modelslengthmax
1条回答
网友
1楼 · 发布于 2024-10-06 16:25:11

对于Django>;=2.0,存在一个很好的解决方案。可以通过匹配的鸟的数量来注释鸟类,并过滤至少匹配一只鸟或所需数量的鸟类。在

from django.db.models import Count

    ...
    person_birds = set(self.birds_to_see.all())
    aviaries = (
        Aviary.objects
        .annotate(bird_match_count=Count('birds', filter=Q(birds__in=person_birds)))
        .filter(bird_match_count__gt=0)
    )

然后,通过bird_match_count=len(person_birds)过滤一个新的查询集,或者在Python中过滤原始的queryset,或者按bird_match_count对其进行排序,都是很简单的。在

Django<;2.0将需要引用中介模型AviaryBirds,并且将更加详细。在


通过读取SQL验证

^{pr2}$

相关问题 更多 >