Opened 5 years ago
Closed 5 years ago
#30957 closed Cleanup/optimization (wontfix)
Inconsistent slice behaviour on cached vs non-cached result lists in QuerySets.
Reported by: | Karolis Ryselis | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
consider a model
class Good(models.Model): title = models.CharField(max_length=16)
Suppose we have created some objects of this model in database.
Getting a slice of existing queryset returns a new queryset:
g = Good.objects.all() print(type(g[0:1]))
outputs
<class 'django.db.models.query.QuerySet'>
however, getting a slice on an evaluated queryset returns a list, not queryset:
g = Good.objects.all() list(g) # force evaluation print(type(g[0:1]))
outputs
<class 'list'>
This happens because __getitem__
in QuerySet
uses result cache if it's available, and result cache is always saved as list. Excerpt from QuerySet,__getitem__
:
if self._result_cache is not None: return self._result_cache[k]
Excerpt from QuerySet._fetch_all
:
if self._result_cache is None: self._result_cache = list(self._iterable_class(self))
If _result_cache
is None
, then __getitem__
makes a query and returns a proper QuerySet. This produces extremely hard-to-catch bugs, because the return type depends on QuerySet evaluation state.
The error was reproduced in version 2.2.6
Change History (1)
comment:1 by , 5 years ago
Component: | Uncategorized → Database layer (models, ORM) |
---|---|
Resolution: | → wontfix |
Status: | new → closed |
Summary: | Inconsistent slice behaviour on cached vs non-cached result lists in QuerySets → Inconsistent slice behaviour on cached vs non-cached result lists in QuerySets. |
Type: | Uncategorized → Cleanup/optimization |
Version: | 2.2 → master |
Thanks for this ticket, however this is not a bug. This documented behavior is by design.