[3.2.x] Fixed #32812 -- Restored immutability of named values from QuerySet.values_list().

Regression in 981a072dd4.

Thanks pirelle for the report.

Backport of 0393b9262d from main
This commit is contained in:
Takayuki Hirayama 2021-06-04 00:32:55 +09:00 committed by Mariusz Felisiak
parent b6e3290383
commit 8ec5b7403d
5 changed files with 25 additions and 2 deletions

View File

@ -45,4 +45,8 @@ def create_namedtuple_class(*names):
def __reduce__(self):
return unpickle_named_row, (names, tuple(self))
return type('Row', (namedtuple('Row', names),), {'__reduce__': __reduce__})
return type(
'Row',
(namedtuple('Row', names),),
{'__reduce__': __reduce__, '__slots__': ()},
)

View File

@ -9,4 +9,6 @@ Django 3.2.5 fixes several bugs in 3.2.4.
Bugfixes
========
* ...
* Fixed a regression in Django 3.2 that caused a crash of
``QuerySet.values_list(…, named=True)`` after ``prefetch_related()``
(:ticket:`32812`).

View File

View File

@ -0,0 +1,10 @@
from django.db.models.utils import create_namedtuple_class
from django.test import SimpleTestCase
class NamedTupleClassTests(SimpleTestCase):
def test_immutability(self):
row_class = create_namedtuple_class('field1', 'field2')
row = row_class('value1', 'value2')
with self.assertRaises(AttributeError):
row.field3 = 'value3'

View File

@ -309,6 +309,13 @@ class PrefetchRelatedTests(TestDataMixin, TestCase):
list(Book.objects.prefetch_related(relation))
self.assertEqual(add_q_mock.call_count, 1)
def test_named_values_list(self):
qs = Author.objects.prefetch_related('books')
self.assertCountEqual(
[value.name for value in qs.values_list('name', named=True)],
['Anne', 'Charlotte', 'Emily', 'Jane'],
)
class RawQuerySetTests(TestDataMixin, TestCase):
def test_basic(self):