当Django的ORM使用Q?

时间:2011-02-09 00:39:35

标签: django django-queryset django-q

我正在尝试使用Django的Q功能来生成一些AND和OR SQL查询,但不幸的是我似乎无法弄清楚Django如何以及​​何时生成它的条件。我有一个更复杂的查询,但我决定削减它以查看发生了什么。

没有Q()的示例:

>>> MyObject.objects.filter(status='VALUE').count()
6

现在Q():

>>> MyObject.objects.filter(Q(status='VALUE')).count()
22

这是从django.db.connection生成的查询:

[{'time': '0.001', 'sql': 'SELECT COUNT(*) FROM "myobjects_myobject" WHERE "myobjects_myobject"."status" = E\'VALUE\' '}, {'time': '0.001', 'sql': 'SELECT COUNT(*) FROM "myobjects_myobject"'}]

然后我添加了另一个值:

>>> MyObject.objects.filter(Q(status='VALUE'), Q(created_date__lt=a_date_value)).count()
22

但是当我改变那个顺序时,我得到了:

>>> MyObject.objects.filter(Q(created_date__lt=a_date_value), Q(status='VALUE'), ).count()
6

使用SQL:

[{'time': '0.001', 'sql': 'SELECT COUNT(*) FROM "myobjects_myobject" WHERE "myobjects_myobject"."created_date" < E\'2011-02-09 00:24:55.927825\' '}, {'time': '0.001', 'sql': 'SELECT COUNT(*) FROM "myobjects_myobject" WHERE "myobjects_myobject"."status" = E\'VALUE\' '}

所以我觉得它每次都忽略了第一个Q值 - 这是预期的行为吗?

1 个答案:

答案 0 :(得分:1)

如果这是您执行的实际代码,而不是偶然发现Django中的错误。

以下内容应该有相同的结果:

>>> MyObject.objects.filter(status='VALUE').count()
>>> MyObject.objects.filter(Q(status='VALUE')).count()

这并不重要,但Q对象从未真正需要。

而不是:

>>> qs = MyObject.objects.all()
>>> qs.filter(Q(status='VALUE') | Q(status='UNKNOWN')).count()

您也可以使用:

>>> qs = MyObject.objects.all()
>>> (qs.filter(status='VALUE') | qs.filter(status='UNKNOWN')).count()