开发者

When Django's ORM Uses Q?

开发者 https://www.devze.com 2023-02-09 03:41 出处:网络
I am trying to use Django\'s Q functionality to generate some AND and OR SQL queries, but unfortunately I can\'t seem to figure out how and when Django generates it\'s conditionals. I had a more compl

I am trying to use Django's Q functionality to generate some AND and OR SQL queries, but unfortunately I can't seem to figure out how and when Django generates it's conditionals. I had a more complex query but I decided to pare it down to see what was going on.

Example without Q():

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

And now Q():

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

And the queries this generates from 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"'}]

And then I add a another value:

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

But when I reverse that order I get:

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

With the 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\' '}

So it looks like to me like it's ignoring the first Q value each time - is 开发者_如何学运维this the expected behavior?


If this is the actual code you've executed than you've stumbled upon a bug in Django.

The following should have identical results:

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

It doesn't really matter that much though, Q objects are never really needed.

Instead of this:

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

You can also use this:

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

精彩评论

暂无评论...
验证码 换一张
取 消