summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Johnson <me@adamj.eu>2025-09-19 12:27:05 +0200
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-09-30 08:46:28 +0200
commit8b241f84e25f679c459393dab2947c8354eb01a9 (patch)
treeed056969aaa65e2989fa74f1f6cc50cf0bbd180e
parentd29852ae725f673843c46085bb51cbc740d374d7 (diff)
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>
-rw-r--r--django/db/models/query.py12
-rw-r--r--docs/internals/deprecation.txt3
-rw-r--r--docs/releases/6.1.txt4
-rw-r--r--tests/lookup/tests.py42
4 files changed, 54 insertions, 7 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 8edae41e5f..b404fd1875 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -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")}
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index f2a6e9b545..2473d2b4f7 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -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:
diff --git a/docs/releases/6.1.txt b/docs/releases/6.1.txt
index 56a222f3e3..97a9d05d9d 100644
--- a/docs/releases/6.1.txt
+++ b/docs/releases/6.1.txt
@@ -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
=======================
diff --git a/tests/lookup/tests.py b/tests/lookup/tests.py
index f6f73e9fac..5b9dd8e5ec 100644
--- a/tests/lookup/tests.py
+++ b/tests/lookup/tests.py
@@ -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,