Когда в Django ORM используется Q? - PullRequest
0 голосов
/ 09 февраля 2011

Я пытаюсь использовать функциональность Q в Django для генерации некоторых SQL-запросов AND и OR, но, к сожалению, я не могу понять, как и когда 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 Ответ

1 голос
/ 09 февраля 2011

Если это именно тот код, который вы выполнили, чем вы наткнулись на ошибку в 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()
...