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()
精彩评论