Django Q& Q与filter.filter

时间:2016-07-28 13:17:52

标签: sql django orm

在搜索错误时,我发现以下两个语句做了不同的事情:

查询1

Order.objects \
  .filter(items__name__icontains="Foo") \
  .filter(items__name__icontains="Bar") \
  .distinct()

查询2

Order.objects \
  .filter(
    Q(items__name__icontains="Foo") &
    Q(items__name__icontains="Bar")
  ) \
  .distinct()

结果如下:

  • 查询1 包含的订单中包含 “Bar”的项目。例如,一个项目的名称是“Foo”,而另一个项目的名称是“Bar”
  • 查询2 但是只包含至少一个包含所有关键字的商品的订单,例如名称为<的商品em>“Foo Bar”

查看查询,我可以看到filter()方法为查询添加了另一个INNER JOIN而另一个没有。

我可以看到这背后的原因,但我真的很想知道这是不是预期的行为。

1 个答案:

答案 0 :(得分:2)

区别在于第一个查询有两个filter()个调用,第二个查询只有一个Q()个调用。

第一个查询尝试查找包含“Foo”的相关项目和包含“Bar”的相关项目的对象。第二个查询尝试查找包含单个相关项目的项目,该项目包含“Foo”和“Bar”

使用Order.object.filter( Q(items__name__icontains="Foo" ).filter( Q(items__name__icontains="Bar") ) 个对象的事实并不重要 - 您可以将第一个查询更改为:

Q()

然而,在您的第二个Query 2 m中需要.filter(items__name__icontains="Foo", items__name__icontains="Bar"),因为在{{1}}中重复关键字参数将是无效的Python

有关详细信息,请参阅spanning multi-values relationships上的文档。