Django过滤器的queryset __in只适用于列表中的项目。

问题描述 投票:0回答:1

模型。

class Tag(models.Model):
    name = models.CharField(max_length=20)


class Post(models.Model):
    tags = models.ManyToManyField(Tag)
    title = models.CharField(max_length=20)

数据。

a_post=Post.objects.create(title='a')
ab_post=Post.objects.create(title='ab')
ac_post=Post.objects.create(title='ac')
a_tag=a_post.tags.create(name='a')
ab_post.tags.add(a_tag)
b_tag=ab_post.tags.create(name='b')
ac_post.tags.add(a_tag)
ac_post=ac_post.tags.create(name='c')

我想查询所有列表中只有标签的帖子,其他标签的帖子不应返回。有其他标签的帖子不应该被返回.像这样的代码.应该返回[a_post, ab_post]:

Post.objects.filter(tags__name__only_in=['a','b']).all()

应该返回[a_post, ab_post]。

我已经读过了 这个. 链式过滤器不会有任何帮助。有什么想法吗?

django-queryset django-filter
1个回答
1
投票

你可以检查是否有大量的 Tag的标签总数相同。

from django.db.models import Count, Q

Post.objects.annotate(
    ntags=Count('tags')
).filter(
    ntags=Count('tags', filter=Q(tags__name__in=['a', 'b'])),
    ntags__gt=0
)

因此,第一个过滤器检查相关标签的总数是否与名字为 'a''b'. 如果数量不同,我们就知道有一个名称不同的标签。

第二个过滤器检查标签数是否大于零,以排除没有标签的匹配。

© www.soinside.com 2019 - 2024. All rights reserved.