首页 > 解决方案 > Django Q 对象未正确链接

问题描述

我正在查询一个多对多字段(标签)。这些值来自一个列表:

tag_q = Q()

tag_list = ["work", "friends"]
for tag in tag_list:
    tag_q &= Q(tags__tag=tag)

Post.objects.filter(tag_q)

当我只有一个值时,它可以完美地工作,但是当更多的对象被堆叠时,它总是返回一个空的查询集。

我没有使用 tags__tag__in=tag_list 因为它返回的任何帖子都包含标签列表中的任何标签(一个 OR 过滤器),我在这里需要一个 AND 过滤器。

这是我的模型:

class Tag(models.Model):
    tag = models.CharField(max_length=19, choices=TagChoices.choices())

class Post(models.Model):
    tags = models.ManyToManyField(Tag, related_name='posts', blank=True)

这是在过滤器查询中传递的 Q 对象:

(AND: ('tags__tag', 'work'), ('tags__tag', 'friends')

标签: djangodjango-querysetdjango-ormdjango-q

解决方案


您不能使用这样的Q对象:过滤器是存在量词,而不是通用量词。这意味着您正在寻找一个同时具有名称的单曲Tagtagworkfriends

您可以做的是使用标签列表,然后计算Tags 的数量是否与要搜索的项目数相同,例如:

tag_list = ['work', 'friends']

Post.objects.filter(tags__tag__in=tag_list).annotate(
    ntags=Count('tags')
).filter(ntags=len(set(tag_list))

开始,您可以使用.alias(…)[Django-doc]而不是.annotate(…)[Django-doc]

tag_list = ['work', 'friends']

Post.objects.filter(tags__tag__in=tag_list).alias(
    ntags=Count('tags')
).filter(ntags=len(set(tag_list))

推荐阅读