【问题标题】:Django Query Many relation "includes"Django查询许多关系“包括”
【发布时间】:2020-01-16 23:07:23
【问题描述】:

我有以下型号:

class Contact(models.Model):
    email_list = models.ForeignKey(EmailList, related_name='contacts')
    customer = models.ForeignKey('Customer')

class EmailList(models.Model):
    customers = models.ManyToManyField('Customer',
        related_name='lists',
        through='Contact')

class Customer(models.Model):
    email = models.EmailField(max_length=255, unique=True)

现在我想通过 EmailList id 查询属于某个 EmailLists 集的所有客户。我以为我可以用一些东西来查询这个:

all_customers.filter(lists__id__contains=[email_list_1.pk, email_list_2.pk])

这看起来很奇怪,我接受并返回一个空的 Queryset,但令人惊讶的是,它仅在查询 1 个 EmailList 时起作用,例如:

all_customers.filter(lists__id__contains=email_list_1.pk)

所以我的下一步是使用 AND 运算符进行查询:

customers.filter(Q(lists__id__contains=el1.pk) & Q(lists__id__contains=el2.pk))

但返回并清空 QuerySet。我想找到一种方法来查询 lists__id__contains 传递一个可迭代的 id,或者至少找到一种连接子查询的方法

【问题讨论】:

  • __contains 适用于文本,您需要使用__in

标签: django django-models django-orm


【解决方案1】:

这个失败的原因是因为__contains lookup [Django-doc]适用于文本,如果正确的操作数不是字符串,它会将其转换为字符串。因此,您基本上可以查询具有子字符串 '[1, 4]' 的内容(带有 14 id,这些可能不同)。

客户在任何个列表中

您需要在这里使用__in lookup [Django-doc]

all_customers.filter(<b>lists__id__in</b>=[email_list_1.pk, email_list_2.pk])

或者你可以使用“逻辑或”:

customers.filter(Q(lists__id=el1.pk) | Q(lists__id=el2.pk))

客户在所有列表中

我们还可以通过注释和过滤来查询所有列表中的客户:

ids = [email_list_1.pk, email_list_2.pk]

all_customers.filter(lists__id__in=ids).annotate(
    nlists=Count('lists')
).filter(
    nlists=len(set(ids))
)

【讨论】:

    猜你喜欢
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 2014-07-14
    • 2011-11-29
    • 2021-03-07
    • 2019-05-18
    • 2017-02-02
    相关资源
    最近更新 更多