#36342: Slicing a QuerySet with a result cache results in a list?
-------------------------------------+-------------------------------------
Reporter: Willem Van Onsem | Owner: (none)
Type: | Status: closed
Cleanup/optimization |
Component: Database layer | Version: 5.2
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Natalia Bidart):
* resolution: => invalid
* status: new => closed
Comment:
Thank you Willem Van Onsem for taking the time to create this report. I
created a test for this:
{{{#!diff
diff --git a/tests/queries/tests.py b/tests/queries/tests.py
index 38b0a5ddfa..10c2b821fc 100644
--- a/tests/queries/tests.py
+++ b/tests/queries/tests.py
@@ -2971,6 +2971,13 @@ class WeirdQuerysetSlicingTests(TestCase):
self.assertQuerySetEqual(Article.objects.values()[n:n], [])
self.assertQuerySetEqual(Article.objects.values_list()[n:n],
[])
+ def test_slice_after_result_cached(self):
+ qs = Article.objects.all().order_by("id")
+ # self.assertIs(bool(qs), True)
+ expected = Article.objects.filter(id__lt=4).order_by("id")
+ self.assertQuerySetEqual(qs[:3], expected)
+ self.assertQuerySetEqual(qs[:3].values("id"),
Article.objects.filter(id__lt=4).values("id"))
+
class EscapingTests(TestCase):
def test_ticket_7302(self):
}}}
If `self.assertIs(bool(qs), True)` is commented out, the test passes. If
it's not, the test fails with:
{{{
======================================================================
ERROR: test_slice_after_result_cached
(queries.tests.WeirdQuerysetSlicingTests.test_slice_after_result_cached)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/nessita/fellowship/django/tests/queries/tests.py", line
2979, in test_slice_after_result_cached
self.assertQuerySetEqual(qs[:3].values("id"),
Article.objects.filter(id__lt=4).values("id"))
^^^^^^^^^^^^^
AttributeError: 'list' object has no attribute 'values'
}}}
I couldn't find a dupe, and I was inclined to accept this until I found
the explicit docs about this. From
https://docs.djangoproject.com/en/5.2/ref/models/querysets/:
5.2
> Slicing. As explained in Limiting QuerySets, a QuerySet can be sliced,
using Python’s array-slicing syntax. Slicing an unevaluated QuerySet
usually returns another unevaluated QuerySet, but Django will execute the
database query if you use the “step” parameter of slice syntax, and will
return a list. Slicing a QuerySet that has been evaluated also returns a
list.
> Also note that even though slicing an unevaluated QuerySet returns
another unevaluated QuerySet, modifying it further (e.g., adding more
filters, or modifying ordering) is not allowed, since that does not
translate well into SQL and it would not have a clear meaning either.
Closing as `invalid` given the above.
--
Ticket URL: <https://code.djangoproject.com/ticket/36342#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/django-updates/010701965e6143e8-f06b66fc-c9b2-4ce2-9868-55be3104b609-000000%40eu-central-1.amazonses.com.