Ticket #17681: emptyqs_removal.diff
File emptyqs_removal.diff, 12.8 KB (added by , 13 years ago) |
---|
-
django/contrib/auth/models.py
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index eb39868..fb5ad10 100644
a b class AnonymousUser(object): 408 408 is_staff = False 409 409 is_active = False 410 410 is_superuser = False 411 _groups = EmptyManager( )412 _user_permissions = EmptyManager( )411 _groups = EmptyManager(model=User) 412 _user_permissions = EmptyManager(model=User) 413 413 414 414 def __init__(self): 415 415 pass -
django/db/models/manager.py
diff --git a/django/db/models/manager.py b/django/db/models/manager.py index e1bbf6e..28a320a 100644
a b 1 1 import copy 2 2 from django.db import router 3 from django.db.models.query import QuerySet, EmptyQuerySet,insert_query, RawQuerySet3 from django.db.models.query import QuerySet, insert_query, RawQuerySet 4 4 from django.db.models import signals 5 5 from django.db.models.fields import FieldDoesNotExist 6 6 … … class Manager(object): 46 46 # Tracks each time a Manager instance is created. Used to retain order. 47 47 creation_counter = 0 48 48 49 def __init__(self ):49 def __init__(self, model=None): 50 50 super(Manager, self).__init__() 51 51 self._set_creation_counter() 52 self.model = None52 self.model = model 53 53 self._inherited = False 54 54 self._db = None 55 55 … … class Manager(object): 101 101 ####################### 102 102 103 103 def get_empty_query_set(self): 104 return EmptyQuerySet(self.model, using=self._db)104 return QuerySet(self.model, using=self.db).none() 105 105 106 106 def get_query_set(self): 107 107 """Returns a new QuerySet object. Subclasses can override this method -
django/db/models/query.py
diff --git a/django/db/models/query.py b/django/db/models/query.py index 41c24c7..0d91ce9 100644
a b class QuerySet(object): 31 31 """ 32 32 def __init__(self, model=None, query=None, using=None): 33 33 self.model = model 34 # EmptyQuerySet instantiates QuerySet with model as None35 34 self._db = using 36 35 self.query = query or sql.Query(self.model) 37 36 self._result_cache = None … … class QuerySet(object): 210 209 211 210 def __and__(self, other): 212 211 self._merge_sanity_check(other) 213 if isinstance(other, EmptyQuerySet):214 return other._clone()215 212 combined = self._clone() 216 213 combined.query.combine(other.query, sql.AND) 217 214 return combined … … class QuerySet(object): 219 216 def __or__(self, other): 220 217 self._merge_sanity_check(other) 221 218 combined = self._clone() 222 if isinstance(other, EmptyQuerySet):223 return combined224 219 combined.query.combine(other.query, sql.OR) 225 220 return combined 226 221 … … class QuerySet(object): 600 595 """ 601 596 Returns an empty QuerySet. 602 597 """ 603 return self._clone(klass=EmptyQuerySet) 598 c = self._clone() 599 c.query.set_empty() 600 return c 604 601 605 602 ################################################################## 606 603 # PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET # … … class DateQuerySet(QuerySet): 1116 1113 c._setup_query() 1117 1114 return c 1118 1115 1119 1120 class EmptyQuerySet(QuerySet):1121 def __init__(self, model=None, query=None, using=None):1122 super(EmptyQuerySet, self).__init__(model, query, using)1123 self._result_cache = []1124 1125 def __and__(self, other):1126 return self._clone()1127 1128 def __or__(self, other):1129 return other._clone()1130 1131 def count(self):1132 return 01133 1134 def delete(self):1135 pass1136 1137 def _clone(self, klass=None, setup=False, **kwargs):1138 c = super(EmptyQuerySet, self)._clone(klass, setup=setup, **kwargs)1139 c._result_cache = []1140 return c1141 1142 def iterator(self):1143 # This slightly odd construction is because we need an empty generator1144 # (it raises StopIteration immediately).1145 yield iter([]).next()1146 1147 def all(self):1148 """1149 Always returns EmptyQuerySet.1150 """1151 return self1152 1153 def filter(self, *args, **kwargs):1154 """1155 Always returns EmptyQuerySet.1156 """1157 return self1158 1159 def exclude(self, *args, **kwargs):1160 """1161 Always returns EmptyQuerySet.1162 """1163 return self1164 1165 def complex_filter(self, filter_obj):1166 """1167 Always returns EmptyQuerySet.1168 """1169 return self1170 1171 def select_related(self, *fields, **kwargs):1172 """1173 Always returns EmptyQuerySet.1174 """1175 return self1176 1177 def annotate(self, *args, **kwargs):1178 """1179 Always returns EmptyQuerySet.1180 """1181 return self1182 1183 def order_by(self, *field_names):1184 """1185 Always returns EmptyQuerySet.1186 """1187 return self1188 1189 def distinct(self, fields=None):1190 """1191 Always returns EmptyQuerySet.1192 """1193 return self1194 1195 def extra(self, select=None, where=None, params=None, tables=None,1196 order_by=None, select_params=None):1197 """1198 Always returns EmptyQuerySet.1199 """1200 assert self.query.can_filter(), \1201 "Cannot change a query once a slice has been taken"1202 return self1203 1204 def reverse(self):1205 """1206 Always returns EmptyQuerySet.1207 """1208 return self1209 1210 def defer(self, *fields):1211 """1212 Always returns EmptyQuerySet.1213 """1214 return self1215 1216 def only(self, *fields):1217 """1218 Always returns EmptyQuerySet.1219 """1220 return self1221 1222 def update(self, **kwargs):1223 """1224 Don't update anything.1225 """1226 return 01227 1228 def aggregate(self, *args, **kwargs):1229 """1230 Return a dict mapping the aggregate names to None1231 """1232 for arg in args:1233 kwargs[arg.default_alias] = arg1234 return dict([(key, None) for key in kwargs])1235 1236 # EmptyQuerySet is always an empty result in where-clauses (and similar1237 # situations).1238 value_annotation = False1239 1240 1116 def get_klass_info(klass, max_depth=0, cur_depth=0, requested=None, 1241 1117 only_load=None, local_only=False): 1242 1118 """ -
django/db/models/sql/compiler.py
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 72948f9..6808b34 100644
a b class SQLCompiler(object): 60 60 """ 61 61 if with_limits and self.query.low_mark == self.query.high_mark: 62 62 return '', () 63 64 63 self.pre_sql_setup() 65 64 # After executing the query, we must get rid of any joins the query 66 65 # setup created. So, take note of alias counts before the query ran. -
django/db/models/sql/query.py
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index a78df34..825647d 100644
a b from django.db.models.sql.constants import * 22 22 from django.db.models.sql.datastructures import EmptyResultSet, Empty, MultiJoin 23 23 from django.db.models.sql.expressions import SQLEvaluator 24 24 from django.db.models.sql.where import (WhereNode, Constraint, EverythingNode, 25 ExtraWhere, AND, OR )25 ExtraWhere, AND, OR, NothingNode) 26 26 from django.core.exceptions import FieldError 27 27 28 28 __all__ = ['Query', 'RawQuery'] … … class Query(object): 426 426 427 427 return number 428 428 429 def set_empty(self): 430 """ 431 Turn this queryset into one which will return nothing when evaluated. 432 """ 433 self.where = self.where_class() 434 self.where.add(NothingNode(), AND) 435 429 436 def has_results(self, using): 430 437 q = self.clone() 431 438 q.add_extra({'a': 1}, None, None, None, None, None) -
django/db/models/sql/where.py
diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py index 1455ba6..36cf82d 100644
a b class WhereNode(tree.Node): 36 36 """ 37 37 default = AND 38 38 39 def __init__(self, *args, **kwargs): 40 super(WhereNode, self).__init__(*args, **kwargs) 41 39 42 def add(self, data, connector): 40 43 """ 41 44 Add a node to the where-tree. If the data is a list or tuple, it is … … class WhereNode(tree.Node): 252 255 if hasattr(child[3], 'relabel_aliases'): 253 256 child[3].relabel_aliases(change_map) 254 257 258 255 259 class EverythingNode(object): 256 260 """ 257 261 A node that matches everything. -
docs/ref/models/querysets.txt
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 103cae1..886cbf6 100644
a b none 601 601 602 602 .. method:: none() 603 603 604 Returns a n ``EmptyQuerySet`` — a ``QuerySet`` subclass that always evaluates to605 an empty list. This can be used in cases where you know that you should return604 Returns a ``QuerySet`` that always evaluates to an empty list. No query should 605 be executed. This can be used in cases where you know that you should return 606 606 an empty result set and your caller is expecting a ``QuerySet`` object (instead 607 607 of returning an empty list, for example.) 608 608 -
tests/modeltests/get_object_or_404/tests.py
diff --git a/tests/modeltests/get_object_or_404/tests.py b/tests/modeltests/get_object_or_404/tests.py index 280720f..992a2f3 100644
a b class GetObjectOr404Tests(TestCase): 53 53 get_object_or_404, Author.objects.all() 54 54 ) 55 55 56 # Using a n EmptyQuerySet raises a Http404 error.56 # Using a empty queryset raises a Http404 error. 57 57 self.assertRaises(Http404, 58 58 get_object_or_404, Article.objects.none(), title__contains="Run" 59 59 ) -
tests/modeltests/lookup/tests.py
diff --git a/tests/modeltests/lookup/tests.py b/tests/modeltests/lookup/tests.py index 3571e21..5333402 100644
a b class LookupTests(TestCase): 436 436 ]) 437 437 438 438 def test_none(self): 439 # none() returns an EmptyQuerySet that behaves like any other QuerySet object439 # none() returns an empty queryset that behaves like any other QuerySet object 440 440 self.assertQuerysetEqual(Article.objects.none(), []) 441 441 self.assertQuerysetEqual( 442 442 Article.objects.none().filter(headline__startswith='Article'), []) -
tests/regressiontests/queries/tests.py
diff --git a/tests/regressiontests/queries/tests.py b/tests/regressiontests/queries/tests.py index ded3e8f..a706c82 100644
a b from django.conf import settings 8 8 from django.core.exceptions import FieldError 9 9 from django.db import DatabaseError, connection, connections, DEFAULT_DB_ALIAS 10 10 from django.db.models import Count 11 from django.db.models.query import Q, ITER_CHUNK_SIZE , EmptyQuerySet11 from django.db.models.query import Q, ITER_CHUNK_SIZE 12 12 from django.test import TestCase, skipUnlessDBFeature 13 13 from django.utils import unittest 14 14 from django.utils.datastructures import SortedDict … … class Queries1Tests(BaseQuerysetTest): 655 655 ['<Item: one>', '<Item: two>'] 656 656 ) 657 657 658 def test_ticket7235(self):659 # An EmptyQuerySet should not raise exceptions if it is filtered.660 q = EmptyQuerySet()661 self.assertQuerysetEqual(q.all(), [])662 self.assertQuerysetEqual(q.filter(x=10), [])663 self.assertQuerysetEqual(q.exclude(y=3), [])664 self.assertQuerysetEqual(q.complex_filter({'pk': 1}), [])665 self.assertQuerysetEqual(q.select_related('spam', 'eggs'), [])666 self.assertQuerysetEqual(q.annotate(Count('eggs')), [])667 self.assertQuerysetEqual(q.order_by('-pub_date', 'headline'), [])668 self.assertQuerysetEqual(q.distinct(), [])669 self.assertQuerysetEqual(670 q.extra(select={'is_recent': "pub_date > '2006-01-01'"}),671 []672 )673 q.query.low_mark = 1674 self.assertRaisesMessage(675 AssertionError,676 'Cannot change a query once a slice has been taken',677 q.extra, select={'is_recent': "pub_date > '2006-01-01'"}678 )679 self.assertQuerysetEqual(q.reverse(), [])680 self.assertQuerysetEqual(q.defer('spam', 'eggs'), [])681 self.assertQuerysetEqual(q.only('spam', 'eggs'), [])682 683 658 def test_ticket7791(self): 684 659 # There were "issues" when ordering and distinct-ing on fields related 685 660 # via ForeignKeys. … … class CloneTests(TestCase): 1613 1588 1614 1589 class EmptyQuerySetTests(TestCase): 1615 1590 def test_emptyqueryset_values(self): 1616 # #14366 -- Calling .values() on an EmptyQuerySet and then cloning that1591 # #14366 -- Calling .values() on an empty queryset and then cloning that 1617 1592 # should not cause an error" 1618 1593 self.assertQuerysetEqual( 1619 1594 Number.objects.none().values('num').order_by('num'), []