Django Q 对象没有正确链接
Django Q object not chaining correctly
我正在查询 ManyToMany 字段(标签)。这些值来自列表:
tag_q = Q()
tag_list = ["work", "friends"]
for tag in tag_list:
tag_q &= Q(tags__tag=tag)
Post.objects.filter(tag_q)
当我只有一个值时,它可以完美地工作,但是当更多的对象被堆叠时,它总是return一个空的查询集。
我没有使用 tags__tag__in=tag_list 因为它 returned 任何 post 包含标签列表中的任何标签(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')
您不能像那样使用 Q
对象:过滤器是 存在的 量词,而不是通用量词。这意味着您正在寻找一个 single Tag
tag
name work
and friends
at 同样次。
你可以做的是处理标签列表,然后计算 Tag
的数量是否与要搜索的项目数量相同,例如:
tag_list = ['work', 'friends']
Post.objects.filter(tags__tag__in=tag_list).annotate(
<strong>ntags=Count('tags')</strong>
).filter(<strong>ntags=len(set(tag_list)</strong>)
因为 django-3.2, you can work with .alias(…)
[Django-doc] instead of .annotate(…)
[Django-doc]:
tag_list = ['work', 'friends']
Post.objects.filter(tags__tag__in=tag_list).alias(
<strong>ntags=Count('tags')</strong>
).filter(<strong>ntags=len(set(tag_list)</strong>)
我正在查询 ManyToMany 字段(标签)。这些值来自列表:
tag_q = Q()
tag_list = ["work", "friends"]
for tag in tag_list:
tag_q &= Q(tags__tag=tag)
Post.objects.filter(tag_q)
当我只有一个值时,它可以完美地工作,但是当更多的对象被堆叠时,它总是return一个空的查询集。
我没有使用 tags__tag__in=tag_list 因为它 returned 任何 post 包含标签列表中的任何标签(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')
您不能像那样使用 Q
对象:过滤器是 存在的 量词,而不是通用量词。这意味着您正在寻找一个 single Tag
tag
name work
and friends
at 同样次。
你可以做的是处理标签列表,然后计算 Tag
的数量是否与要搜索的项目数量相同,例如:
tag_list = ['work', 'friends']
Post.objects.filter(tags__tag__in=tag_list).annotate(
<strong>ntags=Count('tags')</strong>
).filter(<strong>ntags=len(set(tag_list)</strong>)
因为 django-3.2, you can work with .alias(…)
[Django-doc] instead of .annotate(…)
[Django-doc]:
tag_list = ['work', 'friends']
Post.objects.filter(tags__tag__in=tag_list).alias(
<strong>ntags=Count('tags')</strong>
).filter(<strong>ntags=len(set(tag_list)</strong>)