25

我有一个标记模型实例的 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] 那么我必须什么也得不到。我需要精确匹配。

谢谢

4

1 回答 1

39

One approach is to use chain of filters:

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

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

Now node_query will match node, that has at least three tags with pk 10, 6, 3. To exact matching of three tags:

UPDATE: Thanks to @janos and @Adrián López, the correct answer is:

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)
于 2013-05-01T19:07:10.003 回答