qwe*_*i90 3 python django python-2.7 django-1.9
我有两个模型
class Tag(models.Model):
key = models.CharField(max_length=200)
class Post(models.Model):
name = models.CharField(max_length=200)
tags = models.ManyToManyField(Tag)
Run Code Online (Sandbox Code Playgroud)
我正在尝试过滤带有标签列表的帖子。让我们说标签heat和warm。我将在我的 api 函数 ( ['heat', 'warm']) 中获得一个标签列表。我想过滤所有包含其键在列表中的标签的 Post 数据。我尝试了很多类型,但没有得到正确的输出。有没有办法在单个查询中做到这一点?
虽然Wilfried 的答案是正确的,并且对于很多用例来说都是完美的,但值得注意的是,在 SQL 级别上,可能DISTINCT会对性能产生影响,特别是如果您希望查询匹配大部分数据(取决于数据库和表)尺寸;请参阅此处和此处了解更多详细信息)。
另一个稍微详细一点的选项可以避免这个陷阱,那就是使用throughmodel 和 a 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)
Run Code Online (Sandbox Code Playgroud)
以及相应的查询:
tags = Tagging.objects.filter(tag__key__in=['heat', 'warm'])
Post.objects.filter(pk__in=models.Subquery(tags.values('post__pk')))
Run Code Online (Sandbox Code Playgroud)
使用.explain(analyze=True)(在 django 2.1 中引入)将帮助您做出明智的决定。
具有此标签键的所有帖子等于heat或warm
Post.objects.filter(tags__key_in=['heat', 'warm'])
Run Code Online (Sandbox Code Playgroud)
添加 distinct 以避免重复:
Post.objects.filter(tags__key_in=['heat', 'warm']).distinct()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
990 次 |
| 最近记录: |