我有两个型号
heat
我试图过滤掉带有标签列表的帖子。让我们说标签warm
和['heat', 'warm']
。我将在我的api函数(PercentRelativeLayout
)中获得一个标签列表。我想过滤所有包含其键位于列表中的标签的Post数据。我尝试了很多类型,并没有得到正确的输出。有没有办法在单个查询上执行此操作?
答案 0 :(得分:2)
此标记键的所有帖子等于heat
或warm
Post.objects.filter(tags__key_in=['heat', 'warm'])
添加distinct以避免重复:
Post.objects.filter(tags__key_in=['heat', 'warm']).distinct()
答案 1 :(得分:0)
尽管Wilfried's answer是正确的并且在许多用例中都很好,但是值得注意的是,在SQL级别,DISTINCT
可能会对性能产生影响,尤其是如果您希望查询匹配数据的很大一部分(取决于数据库和表的大小;有关更多详细信息,请参见例如here和here)。
另一个避免这种陷阱的冗长选项是使用through
模型和Subquery
(在Django 1.11中引入)。基于OP代码:
class Tag(models.Model):
key = models.CharField(max_length=200)
class Post(models.Model):
name = models.CharField(max_length=200)
tags = models.ManyToManyField(Tag, through='Tagging')
class Tagging(models.Model):
tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
以及相应的查询:
tags = Tagging.objects.filter(tag__key__in=['heat', 'warm'])
Post.objects.filter(pk__in=models.Subquery(tags.values('post__pk')))
使用.explain(analyze=True)
(在django 2.1中引入)将帮助您做出明智的决定。