Django:如何过滤多对多字段的子集?

时间:2013-04-28 19:13:30

标签: django

假设我有经典的ArticleTag模型。如何过滤至少包含ArticleA标记的所有B模型。因此,应添加包含标记ABC的文章,但不应包含标记为AD的文章。谢谢!

2 个答案:

答案 0 :(得分:0)

这个问题可能已经过时但我没有在django中找到任何内置解决方案(如__in filter tag)

所以保持你的榜样。我们在文章和标签之间存在M2M关系,并希望获得具有给定标签A,B,C的所有文章。 在Django中没有直接的解决方案,我们必须回想一下SQL(别担心,我们仍然可以在Django ORM中做所有事情) 在M2M关系中,需要有一个连接两个关系的公共表。我们称之为TagArticle。此表中的一行只是一个标记和一个文章ID。

我们实际需要做的是:

1)过滤常见的TagsArticle表,只获取带有A,B或C标记的行。

2)按文章对找到的行进行分组并计算行数。

3)过滤掉计数小于标签数量的所有行(在我们的例子中为3)

4)现在使用之前的结果

加入或过滤Article表

幸运的是,我们不必直接在Django中访问TagArticle表。伪代码是:

 from django.db.models import Count
 ...
  tags = ['A', 'B', 'C']
  articleQS = Tag.objects.filter(name__in=tags).values('article')
  .annotate(tagCount=Count('article'))
            .filter(catCount=len(tags)).values('article')

        articles = Article.objects.filter(id__in=articleQS)

答案 1 :(得分:-1)

我们说Tag是:

class Tag(models.model):
   article = models.ForeignKey('Article')
   name = models.CharField(max_length=2)

然后我认为你可以这样做:

a_ids = Tag.objects.filter(name='A').values_list('article_id')
b_ids = Tag.objects.filter(name='B').values_list('article_id')
Article.objects.filter(id__in=a_ids).filter(id__in=b_ids)