diff options
| author | Russell Keith-Magee <russell@keith-magee.com> | 2007-01-04 04:00:16 +0000 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2007-01-04 04:00:16 +0000 |
| commit | ddb9b7d57a1da6b8715a62376cbb8605e6b2351b (patch) | |
| tree | 2f8b7afee3bb58c59b2c56ec960110143574f666 | |
| parent | 295f4c9fadfda790215921616b90ad5143aef771 (diff) | |
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
| -rw-r--r-- | django/db/models/query.py | 10 | ||||
| -rw-r--r-- | tests/modeltests/or_lookups/models.py | 15 |
2 files changed, 24 insertions, 1 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py index 53ed63ae5b..f42e8cfd42 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -641,7 +641,15 @@ def get_where_clause(lookup_type, table_prefix, field_name, value): except KeyError: pass 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': return '%s%s BETWEEN %%s AND %%s' % (table_prefix, field_name) elif lookup_type in ('year', 'month', 'day'): diff --git a/tests/modeltests/or_lookups/models.py b/tests/modeltests/or_lookups/models.py index 2de18edc1f..9f926a7373 100644 --- a/tests/modeltests/or_lookups/models.py +++ b/tests/modeltests/or_lookups/models.py @@ -69,6 +69,21 @@ __test__ = {'API_TESTS':""" >>> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3)) [<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 >>> Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye')) [<Article: Hello and goodbye>] |
