nel*_*las 5 python django django-queryset
我想获取具有 2 个特定标签“tag1” AND“tag2”的所有图像。我的简化模型:
class Image(models.Model):
title = models.CharField(max_length=100)
class Tag(models.Model):
name = models.CharField(max_length=64, unique=True)
images = models.ManyToManyField(Image, null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)
连接filter作品:
query = Image.objects.filter(tag__name='tag1').filter(tag__name='tag2')
Run Code Online (Sandbox Code Playgroud)
然而,我认为我可以使用 Django 中的 Q 对象来做到这一点。我正在构建一个复杂的查询,因此使用 Q 会更简单。我将所有参数添加到qobj = Q()using qobj.add(Q(tag__name='tag1'), Q.AND)。但是...以下内容什么也检索不到:
qobj = Q()
qobj.add(Q(tag__name='tag1'), Q.AND)
qobj.add(Q(tag__name='tag2'), Q.AND)
query = Image.objects.filter(qobj)
Run Code Online (Sandbox Code Playgroud)
OR在上面的代码中使用连接器时,一切都按预期工作,正确返回具有 tag1 ORtag2 的图像。
似乎在这种AND情况下,它正在寻找 app_tag_images 中具有两个标签的行,这显然不存在,因为每一行只有一个 image_id 的 tag_id 。
有没有办法用 Q 构建这个查询?
ps:如果需要更多代码细节,请告诉我。
编辑:
这是带有 Q 的查询的 que sql 查询(SELECT为了清楚起见,我清理了大部分列):
SELECT "meta_image"."id", "meta_image"."title"
FROM "meta_image"
INNER JOIN "meta_tag_images" ON ("meta_image"."id" = "meta_tag_images"."image_id")
INNER JOIN "meta_tag" ON ("meta_tag_images"."tag_id" = "meta_tag"."id")
WHERE ("meta_tag"."name" = tag1 AND "meta_tag"."name" = tag2)
Run Code Online (Sandbox Code Playgroud)
OR查询与上面相同(替换AND为OR)。
仅供参考,使用过滤器连接的工作方法打印此查询(也经过简化):
SELECT "meta_image"."id", "meta_image"."title"
FROM "meta_image"
INNER JOIN "meta_tag_images" ON ("meta_image"."id" = "meta_tag_images"."image_id")
INNER JOIN "meta_tag" ON ("meta_tag_images"."tag_id" = "meta_tag"."id")
INNER JOIN "meta_tag_images" T4 ON ("meta_image"."id" = T4."image_id")
INNER JOIN "meta_tag" T5 ON (T4."tag_id" = T5."id")
WHERE ("meta_tag"."name" = tag1 AND T5."name" = tag2)
Run Code Online (Sandbox Code Playgroud)
我什至不知道这种格式!
文档显示 Q 对象用法的方式有什么问题?http://docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q-objects
Image.objects.filter(Q(tag__name='tag1') & Q(tag__name='tag2'))
更新:
我用 m2m 在我的模型上测试了 qobj.add() 方法,它在 1.2.3 上运行良好
它也可以很好地复制和粘贴简化的模型。
您确定您的查询应该返回一些内容吗?
是否标准Q用法Q(tag__name='tag1') & Q(tag__name='tag2')返回结果?
你可以打印吗myquery.query也
让我们缩小范围。