Fixed #2473 -- Added special case for '__in=[]' (empty set) queries, because 'WHERE attr IN ()' is invalid SQL on many backends. Thanks, Gary Wilson.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@4283 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
295f4c9fad
commit
ddb9b7d57a
|
@ -641,7 +641,15 @@ def get_where_clause(lookup_type, table_prefix, field_name, value):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
if lookup_type == 'in':
|
if lookup_type == 'in':
|
||||||
return '%s%s IN (%s)' % (table_prefix, field_name, ','.join(['%s' for v in value]))
|
in_string = ','.join(['%s' for id in value])
|
||||||
|
if in_string:
|
||||||
|
return '%s%s IN (%s)' % (table_prefix, field_name, in_string)
|
||||||
|
else:
|
||||||
|
# Most backends do not accept an empty string inside the IN
|
||||||
|
# expression, i.e. cannot do "WHERE ... IN ()". Since there are
|
||||||
|
# also some backends that do not accept "WHERE false", we instead
|
||||||
|
# use an expression that always evaluates to False.
|
||||||
|
return '0=1'
|
||||||
elif lookup_type == 'range':
|
elif lookup_type == 'range':
|
||||||
return '%s%s BETWEEN %%s AND %%s' % (table_prefix, field_name)
|
return '%s%s BETWEEN %%s AND %%s' % (table_prefix, field_name)
|
||||||
elif lookup_type in ('year', 'month', 'day'):
|
elif lookup_type in ('year', 'month', 'day'):
|
||||||
|
|
|
@ -69,6 +69,21 @@ __test__ = {'API_TESTS':"""
|
||||||
>>> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
|
>>> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
|
||||||
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
|
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
|
||||||
|
|
||||||
|
# You could also use "in" to accomplish the same as above.
|
||||||
|
>>> Article.objects.filter(pk__in=[1,2,3])
|
||||||
|
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
|
||||||
|
|
||||||
|
>>> Article.objects.filter(pk__in=[1,2,3,4])
|
||||||
|
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
|
||||||
|
|
||||||
|
# Passing "in" an empty list returns no results ...
|
||||||
|
>>> Article.objects.filter(pk__in=[])
|
||||||
|
[]
|
||||||
|
|
||||||
|
# ... but can return results if we OR it with another query.
|
||||||
|
>>> Article.objects.filter(Q(pk__in=[]) | Q(headline__icontains='goodbye'))
|
||||||
|
[<Article: Goodbye>, <Article: Hello and goodbye>]
|
||||||
|
|
||||||
# Q arg objects are ANDed
|
# Q arg objects are ANDed
|
||||||
>>> Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye'))
|
>>> Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye'))
|
||||||
[<Article: Hello and goodbye>]
|
[<Article: Hello and goodbye>]
|
||||||
|
|
Loading…
Reference in New Issue