1
0
mirror of https://github.com/django/django.git synced 2025-10-04 12:29:11 +00:00

Fixed #36614 -- Deprecated QuerySet.values_list(flat=True) without a field.

Thanks to Jacob Walls and Simon Charette for their input.

co-authored-by: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
This commit is contained in:
Adam Johnson 2025-09-19 12:27:05 +02:00 committed by Sarah Boyce
parent d29852ae72
commit 8b241f84e2
4 changed files with 54 additions and 7 deletions

View File

@ -1475,6 +1475,18 @@ class QuerySet(AltersData):
"field."
)
elif not fields:
# RemovedInDjango70Warning: When the deprecation ends, replace
# with:
# raise TypeError(
# "'flat' is not valid when values_list is called with no "
# "fields."
# )
warnings.warn(
"Calling values_list() with no field name and flat=True "
"is deprecated. Pass an explicit field name instead, like "
"'pk'.",
RemovedInDjango70Warning,
)
fields = [self.model._meta.concrete_fields[0].attname]
field_names = {f: False for f in fields if not hasattr(f, "resolve_expression")}

View File

@ -56,7 +56,8 @@ details on these changes.
See the :ref:`Django 6.1 release notes <deprecated-features-6.1>` for more
details on these changes.
* ...
* Calling :meth:`.QuerySet.values_list` with ``flat=True`` and no field name
will raise ``TypeError``.
.. _deprecation-removed-in-6.1:

View File

@ -262,7 +262,9 @@ Features deprecated in 6.1
Miscellaneous
-------------
* ...
* Calling :meth:`.QuerySet.values_list` with ``flat=True`` and no field name
is deprecated. Pass an explicit field name, like
``values_list("pk", flat=True)``.
Features removed in 6.1
=======================

View File

@ -30,7 +30,8 @@ from django.db.models.lookups import (
LessThanOrEqual,
)
from django.test import TestCase, skipUnlessDBFeature
from django.test.utils import isolate_apps, register_lookup
from django.test.utils import ignore_warnings, isolate_apps, register_lookup
from django.utils.deprecation import RemovedInDjango70Warning
from .models import (
Article,
@ -500,13 +501,19 @@ class LookupTests(TestCase):
self.assertEqual(arts1.slug, "a1")
self.assertEqual(arts1.headline, "Article 1")
# RemovedInDjango70Warning: When the deprecation ends, remove this
# test.
def test_in_bulk_values_list_flat_empty(self):
arts = Article.objects.values_list(flat=True).in_bulk([])
with ignore_warnings(category=RemovedInDjango70Warning):
arts = Article.objects.values_list(flat=True).in_bulk([])
self.assertEqual(arts, {})
# RemovedInDjango70Warning: When the deprecation ends, remove this
# test.
def test_in_bulk_values_list_flat_all(self):
Article.objects.exclude(pk__in=[self.a1.pk, self.a2.pk]).delete()
arts = Article.objects.values_list(flat=True).in_bulk()
with ignore_warnings(category=RemovedInDjango70Warning):
arts = Article.objects.values_list(flat=True).in_bulk()
self.assertEqual(
arts,
{
@ -515,8 +522,13 @@ class LookupTests(TestCase):
},
)
# RemovedInDjango70Warning: When the deprecation ends, remove this
# test.
def test_in_bulk_values_list_flat_pks(self):
arts = Article.objects.values_list(flat=True).in_bulk([self.a1.pk, self.a2.pk])
with ignore_warnings(category=RemovedInDjango70Warning):
arts = Article.objects.values_list(flat=True).in_bulk(
[self.a1.pk, self.a2.pk]
)
self.assertEqual(
arts,
{
@ -794,8 +806,12 @@ class LookupTests(TestCase):
),
],
)
# RemovedInDjango70Warning: When the deprecation ends, remove this
# assertion.
with ignore_warnings(category=RemovedInDjango70Warning):
qs = Article.objects.values_list(flat=True)
self.assertSequenceEqual(
Article.objects.values_list(flat=True),
qs,
[
self.a5.id,
self.a6.id,
@ -902,6 +918,22 @@ class LookupTests(TestCase):
with self.assertRaises(TypeError):
Article.objects.values_list("id", "headline", flat=True)
# RemovedInDjango70Warning: When the deprecation ends, replace with:
# def test_values_list_flat_empty_error(self):
# msg = (
# "'flat' is not valid when values_list is called with no fields."
# )
# with self.assertRaisesMessage(TypeError, msg):
# Article.objects.values_list(flat=True)
def test_values_list_flat_empty_warning(self):
msg = (
"Calling values_list() with no field name and flat=True "
"is deprecated. Pass an explicit field name instead, like "
"'pk'."
)
with self.assertRaisesMessage(RemovedInDjango70Warning, msg):
Article.objects.values_list(flat=True)
def test_get_next_previous_by(self):
# Every DateField and DateTimeField creates get_next_by_FOO() and
# get_previous_by_FOO() methods. In the case of identical date values,