Django 查询多关系 "includes"

Django Query Many relation "includes"

我有以下型号:

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 查询属于某一组EmailList 的所有客户。我以为我可以用一些东西来查询这个:

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

这看起来很奇怪,我接受 returns 一个空的查询集,但令人惊讶的是它在仅查询 1 个 EmailList 时有效,例如:

all_customers.filter(lists__id__contains=email_list_1.pk)

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

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

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

失败的原因是因为__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])

或者您可以使用 "logical or":

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

该客户在所有 个列表中

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

ids = [email_list_1.pk, email_list_2.pk]

all_customers.filter(<b>lists__id__in</b>=ids).annotate(
    <b>nlists=Count('lists')</b>
).filter(
    <b>nlists=len(set(ids))</b>
)