如何在Django中限制与Q.AND的ManyToMany关系的查询

时间:2011-02-04 01:48:07

标签: 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)

连接filter有效:

query = Image.objects.filter(tag__name='tag1').filter(tag__name='tag2')

但是,我认为我可以使用Django的Q对象来完成它。我正在构建一个复杂的查询,因此使用Q会更直接。我正在使用qobj = Q()将所有参数添加到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)

在上面的代码中使用OR连接器时,所有内容都按预期工作,正确返回包含tag1 OR tag2的图片。

似乎在AND情况下,它正在app_tag_images中查找带有两个标记的行,这显然不存在,因为每行只有一个tag_id用于image_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)

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)

1 个答案:

答案 0 :(得分:0)

我甚至都不知道那种格式!

文档显示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吗?

让我们缩小范围。