【问题标题】:django filter many-to-many with given listdjango使用给定列表过滤多对多
【发布时间】:2018-01-22 06:45:32
【问题描述】:

我想filter 一个通过多对多中间关系连接到第二个模型的 Django 模型。

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

design and expected result

结果应该是只选择人员 A,因为他通过成员资格连接到具有条目 1 和 2 的组。我想使用Q 对象来完成此类任务。

谁能给我一个提示?

【问题讨论】:

    标签: python django object filter many-to-many


    【解决方案1】:

    我认为您想要所有 Person 对象,它们位于您将提供给它的所有组 ID 中。

    解决方案

    from django.db.models import Q
    
    person_qs = Person.objects.exclude(~(Q(group__id=1) & Q(group__id=2)))
    

    在这里,我使用exclude 排除了所有不是1和2的组ID。

    如果您有很多组 ID,您可以使用 reduceoperator 在单个 for 循环中构建查询。

    from functools import reduce
    import operator
    
    query = reduce(operator.and_, (Q(group__id=group_id) for group_id in group_ids))
    
    persons_qs = Person.objects.exclude(~query)
    

    这将形成像Q(group__id=1) & Q(group_id=2) & 这样的查询(等等...)

    【讨论】:

    • 嗨,Sachin,您能解释一下为什么您没有通过常规过滤器而是使用排除和否定运算符吗?
    • excludefilter 形成两个不同的查询。在这种情况下,exclude 所做的是它为每个组运行一个子查询,例如 WHERE NOT (NOT (EXISTS(SELECT(1) from membership_table M1 where group_id = 1 and person.id = M1.person_id) AND NOT (EXISTS ...,而 filter 使用成员资格表执行 INNER JOIN 并执行 WHERE membership_table.group_id = 1 AND membership_table.group_id = 2,因此您可以看到 @ 987654334@操作错误,同一个会员行不能有两个不同的组ID。
    【解决方案2】:

    这里不用Q,就是一个简单的查询。

    Person.objects.filter(group__id__in=[1, 2])
    

    【讨论】:

    • 但这将返回 B 以及正确的 IN 行为类似于 OR?
    猜你喜欢
    • 2016-12-13
    • 1970-01-01
    • 2011-05-29
    • 2014-07-22
    • 1970-01-01
    • 2020-05-27
    • 2011-01-14
    • 1970-01-01
    • 2012-09-09
    相关资源
    最近更新 更多