Django查询集获得精确的多对多查询[重复]

Posted

技术标签:

【中文标题】Django查询集获得精确的多对多查询[重复]【英文标题】:Django queryset get exact manytomany lookup [duplicate] 【发布时间】:2013-04-25 19:37:34 【问题描述】:

我有一个 Tag 模型实例的 pk 列表,比如说

pk_list = [10, 6, 3]

我有另一个带有 m2m 标签字段的模型和一个包含恰好 3 个标签(以上 pks)的实例。

class Node(models.Model):
    ...
    tags = models.ManyToManyField(Tag, related_name='nodes')

我想检索一个包含我的 pk_list 中指定的确切标签集的节点。当我这样做时

Node.objects.filter(tags__in=pk_list)

它返回三个相同实例的列表

[<Node: My node title>, <Node: My node title>, <Node: My node title>]

显然,调用 .get() 不起作用,因为它必须返回单个实例。

那么,我如何检索单个实例? 我必须注意,如果我的 pk_list 不同,例如。 [10, 6] 或 [10, 6, 3, 7] 那么我必须什么也得不到。我需要精确匹配。

谢谢

【问题讨论】:

我正要回答,结果发现帖子是我! 感谢cmets,抱歉重复,我不是故意的。 【参考方案1】:

一种方法是使用过滤器链:

node_query = Node.objects.all()
pk_list = [10, 6, 3]

for pk in pk_list:
    node_query = node_query.filter(tags=pk)

现在 node_query 将匹配节点,该节点具有至少三个标签,pk 10、6、3。要精确匹配三个标签:

更新: 感谢@janos和@Adrián López,正确答案是:

from django.db.models import Count

pk_list = [10, 6, 3]
node_query = Node.objects.annotate(count=Count('tags')).filter(count=len(pk_list))

for pk in pk_list:
    node_query = node_query.filter(tags__pk=pk)

【讨论】:

以上是关于Django查询集获得精确的多对多查询[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 中过滤查询集的多对多

Django如何过滤多对多字段中的对象,而不是原始查询集

逻辑或 Django 多对多查询返回重复结果

在 django 中获取具有多对多关系的复杂查询集

优化大数据集上的多对多关系查询

从 Django 查询中的多对多关系中检索项目