#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.

Reply via email to