Django:M2M字段查询使用'in'列表中的每个值

时间:2018-04-20 08:20:24

标签: python django many-to-many django-queryset

我正在尝试查找Problem个与tags中包含的所有标签相关的对象。

我有以下型号。

class Tag(models.Model):
    name = models.CharField(verbose_name='Tag Name', max_length=50)
    description = models.CharField(verbose_name='Description', max_length=100, null=True, blank=True)

class Problem(models.Model):
    name = models.CharField(verbose_name='Problem Name', max_length=250)
    contest_info = models.ManyToManyField(ContestInfo, verbose_name='Contest Info')
    tags = models.ManyToManyField(Tag, verbose_name='Tags')

我已关注这些帖子:Post-1Post-2
但是,没有工作。

我的方法。

方法1

query = [Q(tags__id__in=[tag]) for tag in tags]
problems = problems.filter(reduce(__and__, query))

返回空的查询集。

方法2

for tag in tags:
    problems &= problems.filter(tags__id__in=[tag])

返回OR而不是AND的结果。 使用intersection()也会得到相同的结果。

我希望得到列表中包含所有标签的问题。怎么做?

N.B:problems是一个查询集,tagsTag个对象的ID列表。

2 个答案:

答案 0 :(得分:1)

对于postgresql你可以做的就是这个(测试过):

from django.contrib.postgres.aggregates import JSONBAgg

problems = Problem.objects.annotate(tags_ids=JSONBAgg('tags__id'))
problems = problems.filter(tags_ids__contains=tags, tags_ids__contained_by=tags)

*其中"标签是标签对象的ID列表。"

答案 1 :(得分:0)

我在this回答后解决了这个问题。感谢@itzMEonTV。
但是,它需要循环,我希望在没有循环的情况下实现这一点。

这是解决方案。

for tag in tags:
    problems = problems.filter(tags__id=tag)