Changeset 2485
- Timestamp:
- 03/03/06 18:19:59 (3 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/magic-removal/django/db/models/query.py
r2457 r2485 96 96 def __getitem__(self, k): 97 97 "Retrieve an item or slice from the set of results." 98 # __getitem__ can't return QuerySet instances, because filter() and99 # order_by() on the result would break badly. This means we don't have100 # to worry about arithmetic with self._limit or self._offset -- they'll101 # both be None at this point.102 98 if self._result_cache is None: 103 99 if isinstance(k, slice): 100 # Offset: 101 if self._offset is None: 102 offset = k.start 103 elif k.start is None: 104 offset = self._offset 105 else: 106 offset = self._offset + k.start 107 # Now adjust offset to the bounds of any existing limit: 108 if self._limit is not None and k.start is not None: 109 limit = self._limit - k.start 110 else: 111 limit = self._limit 112 113 # Limit: 104 114 if k.stop is not None and k.start is not None: 105 limit = k.stop - k.start 115 if limit is None: 116 limit = k.stop - k.start 117 else: 118 limit = min((k.stop - k.start), limit) 106 119 else: 107 limit = k.stop 108 return list(self._clone(_offset=k.start, _limit=limit))[::k.step] 120 if limit is None: 121 limit = k.stop 122 else: 123 if k.stop is not None: 124 limit = min(k.stop, limit) 125 126 if k.step is None: 127 return self._clone(_offset=offset, _limit=limit) 128 else: 129 return list(self._clone(_offset=offset, _limit=limit))[::k.step] 109 130 else: 110 131 return self._clone(_offset=k, _limit=1).get() … … 180 201 latest_by = field_name or self.model._meta.get_latest_by 181 202 assert bool(latest_by), "latest() requires either a field_name parameter or 'get_latest_by' in the model" 203 assert self._limit is None and self._offset is None, \ 204 "Cannot change a query once a slice has been taken." 182 205 return self._clone(_limit=1, _order_by=('-'+latest_by,)).get() 183 206 … … 187 210 that ID. 188 211 """ 212 assert self._limit is None and self._offset is None, \ 213 "Cannot use 'limit' or 'offset' with in_bulk" 189 214 assert isinstance(id_list, (tuple, list)), "in_bulk() must be provided with a list of IDs." 190 215 id_list = list(id_list) … … 199 224 Deletes the records in the current QuerySet. 200 225 """ 226 assert self._limit is None and self._offset is None, \ 227 "Cannot use 'limit' or 'offset' with delete." 228 201 229 del_query = self._clone() 202 230 … … 204 232 del_query._select_related = False 205 233 del_query._order_by = [] 206 del_query._offset = None207 del_query._limit = None208 234 209 235 # Collect all the objects to be deleted, and all the objects that are related to … … 252 278 253 279 def _filter_or_exclude(self, qtype, *args, **kwargs): 280 if len(args) > 0 or len(kwargs) > 0: 281 assert self._limit is None and self._offset is None, \ 282 "Cannot filter a query once a slice has been taken." 283 254 284 clone = self._clone() 255 285 if len(kwargs) > 0: … … 265 295 def order_by(self, *field_names): 266 296 "Returns a new QuerySet instance with the ordering changed." 297 assert self._limit is None and self._offset is None, \ 298 "Cannot reorder a query once a slice has been taken." 267 299 return self._clone(_order_by=field_names) 268 300 … … 272 304 273 305 def extra(self, select=None, where=None, params=None, tables=None): 306 assert self._limit is None and self._offset is None, \ 307 "Cannot change a query once a slice has been taken" 274 308 clone = self._clone() 275 309 if select: clone._select.extend(select) … … 302 336 303 337 def _combine(self, other): 304 if self._distinct != other._distinct: 305 raise ValueException, "Can't combine a unique query with a non-unique query" 338 assert self._limit is None and self._offset is None \ 339 and other._limit is None and other._offset is None, \ 340 "Cannot combine queries once a slice has been taken." 341 assert self._distinct == other._distinct, \ 342 "Cannot combine a unique query with a non-unique query" 306 343 # use 'other's order by 307 344 # (so that A.filter(args1) & A.filter(args2) does the same as django/branches/magic-removal/tests/modeltests/basic/models.py
r2480 r2485 240 240 [Area woman programs in Python, Third article] 241 241 242 # Slices (without step) are lazy: 243 >>> Article.objects.all()[0:5].filter() 244 [Area woman programs in Python, Second article, Third article, Fourth article, Article 6] 245 246 # Slicing again works: 247 >>> Article.objects.all()[0:5][0:2] 248 [Area woman programs in Python, Second article] 249 >>> Article.objects.all()[0:5][:2] 250 [Area woman programs in Python, Second article] 251 >>> Article.objects.all()[0:5][4:] 252 [Article 6] 253 >>> Article.objects.all()[0:5][5:] 254 [] 255 256 # Some more tests! 257 >>> Article.objects.all()[2:][0:2] 258 [Third article, Fourth article] 259 >>> Article.objects.all()[2:][:2] 260 [Third article, Fourth article] 261 >>> Article.objects.all()[2:][2:3] 262 [Article 6] 263 264 # Note that you can't use 'offset' without 'limit' (on some dbs), so this doesn't work: 265 >>> Article.objects.all()[2:] 266 Traceback (most recent call last): 267 ... 268 AssertionError: 'offset' is not allowed without 'limit' 269 270 # Also, once you have sliced you can't filter, re-order or combine 271 >>> Article.objects.all()[0:5].filter(id=1) 272 Traceback (most recent call last): 273 ... 274 AssertionError: Cannot filter a query once a slice has been taken. 275 276 >>> Article.objects.all()[0:5].order_by('id') 277 Traceback (most recent call last): 278 ... 279 AssertionError: Cannot reorder a query once a slice has been taken. 280 281 >>> Article.objects.all()[0:1] & Article.objects.all()[4:5] 282 Traceback (most recent call last): 283 ... 284 AssertionError: Cannot combine queries once a slice has been taken. 285 286 242 287 # An Article instance doesn't have access to the "objects" attribute. 243 288 # That's only available on the class.
