From 2dd9a85819218e481f9bc6e88264c2b1ae5f25e8 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sat, 9 Jan 2010 21:27:39 +0000 Subject: [PATCH] Fixed #7235 -- EmptyQuerySet no longer raises and exception when it's filter()ed (along with some other QuerySet methods). Thanks, taylormarshall git-svn-id: http://code.djangoproject.com/svn/django/trunk@12147 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/models/query.py | 75 +++++++++++++++++++++++++ tests/regressiontests/queries/models.py | 35 +++++++++++- 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index 0b57b1e4bc8c1..4e3326a9cac96 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -1014,6 +1014,81 @@ def iterator(self): # (it raises StopIteration immediately). yield iter([]).next() + def all(self): + """ + Always returns EmptyQuerySet. + """ + return self + + def filter(self, *args, **kwargs): + """ + Always returns EmptyQuerySet. + """ + return self + + def exclude(self, *args, **kwargs): + """ + Always returns EmptyQuerySet. + """ + return self + + def complex_filter(self, filter_obj): + """ + Always returns EmptyQuerySet. + """ + return self + + def select_related(self, *fields, **kwargs): + """ + Always returns EmptyQuerySet. + """ + return self + + def annotate(self, *args, **kwargs): + """ + Always returns EmptyQuerySet. + """ + return self + + def order_by(self, *field_names): + """ + Always returns EmptyQuerySet. + """ + return self + + def distinct(self, true_or_false=True): + """ + Always returns EmptyQuerySet. + """ + return self + + def extra(self, select=None, where=None, params=None, tables=None, + order_by=None, select_params=None): + """ + Always returns EmptyQuerySet. + """ + assert self.query.can_filter(), \ + "Cannot change a query once a slice has been taken" + return self + + def reverse(self): + """ + Always returns EmptyQuerySet. + """ + return self + + def defer(self, *fields): + """ + Always returns EmptyQuerySet. + """ + return self + + def only(self, *fields): + """ + Always returns EmptyQuerySet. + """ + return self + # EmptyQuerySet is always an empty result in where-clauses (and similar # situations). value_annotation = False diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py index aababffbabb3b..43c843756cde1 100644 --- a/tests/regressiontests/queries/models.py +++ b/tests/regressiontests/queries/models.py @@ -8,7 +8,8 @@ from django.conf import settings from django.db import models, DEFAULT_DB_ALIAS -from django.db.models.query import Q, ITER_CHUNK_SIZE +from django.db.models import Count +from django.db.models.query import Q, ITER_CHUNK_SIZE, EmptyQuerySet # Python 2.3 doesn't have sorted() try: @@ -969,6 +970,38 @@ def __unicode__(self): ... break True +Bug #7235 -- an EmptyQuerySet should not raise exceptions if it is filtered. +>>> q = EmptyQuerySet() +>>> q.all() +[] +>>> q.filter(x=10) +[] +>>> q.exclude(y=3) +[] +>>> q.complex_filter({'pk': 1}) +[] +>>> q.select_related('spam', 'eggs') +[] +>>> q.annotate(Count('eggs')) +[] +>>> q.order_by('-pub_date', 'headline') +[] +>>> q.distinct() +[] +>>> q.extra(select={'is_recent': "pub_date > '2006-01-01'"}) +[] +>>> q.query.low_mark = 1 +>>> q.extra(select={'is_recent': "pub_date > '2006-01-01'"}) +Traceback (most recent call last): +... +AssertionError: Cannot change a query once a slice has been taken +>>> q.reverse() +[] +>>> q.defer('spam', 'eggs') +[] +>>> q.only('spam', 'eggs') +[] + Bug #7791 -- there were "issues" when ordering and distinct-ing on fields related via ForeignKeys. >>> len(Note.objects.order_by('extrainfo__info').distinct())