Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added QuerySet.exclude() which does the opposite of QuerySet.filter()…

…. As a side effect, the "ne" lookup type no longer exists. This fixes #966.

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2422 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 9cdd49c1e0cbe8621d162190c43284548e4b0002 1 parent 05bc38b
Jacob Kaplan-Moss jacobian authored
1  django/db/backends/ado_mssql/base.py
View
@@ -119,7 +119,6 @@ def get_random_function_sql():
'iexact': 'LIKE %s',
'contains': 'LIKE %s',
'icontains': 'LIKE %s',
- 'ne': '!= %s',
'gt': '> %s',
'gte': '>= %s',
'lt': '< %s',
1  django/db/backends/mysql/base.py
View
@@ -132,7 +132,6 @@ def get_random_function_sql():
'iexact': 'LIKE %s',
'contains': 'LIKE BINARY %s',
'icontains': 'LIKE %s',
- 'ne': '!= %s',
'gt': '> %s',
'gte': '>= %s',
'lt': '< %s',
1  django/db/backends/postgresql/base.py
View
@@ -107,7 +107,6 @@ def get_random_function_sql():
'iexact': 'ILIKE %s',
'contains': 'LIKE %s',
'icontains': 'ILIKE %s',
- 'ne': '!= %s',
'gt': '> %s',
'gte': '>= %s',
'lt': '< %s',
1  django/db/backends/sqlite3/base.py
View
@@ -131,7 +131,6 @@ def _sqlite_date_trunc(lookup_type, dt):
'iexact': "LIKE %s ESCAPE '\\'",
'contains': "LIKE %s ESCAPE '\\'",
'icontains': "LIKE %s ESCAPE '\\'",
- 'ne': '!= %s',
'gt': '> %s',
'gte': '>= %s',
'lt': '< %s',
3  django/db/models/manager.py
View
@@ -69,6 +69,9 @@ def get(self, *args, **kwargs):
def filter(self, *args, **kwargs):
return self.get_query_set().filter(*args, **kwargs)
+ def exclude(self, *args, **kwargs):
+ return self.get_query_set().exclude(*args, **kwargs)
+
def in_bulk(self, *args, **kwargs):
return self.get_query_set().in_bulk(*args, **kwargs)
19 django/db/models/query.py
View
@@ -244,9 +244,16 @@ def dates(self, field_name, kind, order='ASC'):
def filter(self, *args, **kwargs):
"Returns a new QuerySet instance with the args ANDed to the existing set."
+ return self._filter_or_exclude(Q, *args, **kwargs)
+
+ def exclude(self, *args, **kwargs):
+ "Returns a new QuerySet instance with NOT (arsg) ANDed to the existing set."
+ return self._filter_or_exclude(QNot, *args, **kwargs)
+
+ def _filter_or_exclude(self, qtype, *args, **kwargs):
clone = self._clone()
if len(kwargs) > 0:
- clone._filters = clone._filters & Q(**kwargs)
+ clone._filters = clone._filters & qtype(**kwargs)
if len(args) > 0:
clone._filters = clone._filters & reduce(operator.and_, args)
return clone
@@ -490,7 +497,7 @@ def __or__(self, other):
else:
raise TypeError, other
-class Q:
+class Q(object):
"Encapsulates queries as objects that can be combined logically."
def __init__(self, **kwargs):
self.kwargs = kwargs
@@ -504,6 +511,14 @@ def __or__(self, other):
def get_sql(self, opts):
return parse_lookup(self.kwargs.items(), opts)
+class QNot(Q):
+ "Encapsulates NOT (...) queries as objects"
+
+ def get_sql(self, opts):
+ tables, joins, where, params = super(QNot, self).get_sql(opts)
+ where2 = ['(NOT (%s))' % " AND ".join(where)]
+ return tables, joins, where2, params
+
def get_where_clause(lookup_type, table_prefix, field_name, value):
if table_prefix.endswith('.'):
table_prefix = backend.quote_name(table_prefix[:-1])+'.'
8 tests/modeltests/lookup/models.py
View
@@ -170,4 +170,12 @@ def __repr__(self):
[Article% with percent sign, Article_ with underscore, Article 5, Article 6, Article 4, Article 2, Article 3, Article 7, Article 1]
>>> Article.objects.filter(headline__startswith='Article%')
[Article% with percent sign]
+
+# exclude() is the opposite of filter() when doing lookups:
+>>> Article.objects.filter(headline__contains='Article').exclude(headline__contains='with')
+[Article 5, Article 6, Article 4, Article 2, Article 3, Article 7, Article 1]
+>>> Article.objects.exclude(headline__startswith="Article_")
+[Article% with percent sign, Article 5, Article 6, Article 4, Article 2, Article 3, Article 7, Article 1]
+>>> Article.objects.exclude(headline="Article 7")
+[Article% with percent sign, Article_ with underscore, Article 5, Article 6, Article 4, Article 2, Article 3, Article 1]cl
"""
Please sign in to comment.
Something went wrong with that request. Please try again.