summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2023-01-12 19:31:49 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-01-17 11:49:15 +0100
commit4d78d7338cc5cfaa0afcfc9d240d753328bbf399 (patch)
tree6ca8214f896a7bb1cfbb2d37f6cc9999ea3ade1f
parent139135627650ed6aaaf4c755b82c3bd43f2b8f51 (diff)
downloaddjango-4d78d7338cc5cfaa0afcfc9d240d753328bbf399.tar.gz
Refs #31486 -- Removed ability to pass unsaved model instances to related filters.
Per deprecation timeline.
-rw-r--r--django/db/models/fields/related_lookups.py12
-rw-r--r--docs/releases/5.0.txt2
-rw-r--r--tests/queries/tests.py36
3 files changed, 12 insertions, 38 deletions
diff --git a/django/db/models/fields/related_lookups.py b/django/db/models/fields/related_lookups.py
index afea09b5a9..07a06e1686 100644
--- a/django/db/models/fields/related_lookups.py
+++ b/django/db/models/fields/related_lookups.py
@@ -1,5 +1,3 @@
-import warnings
-
from django.db.models.lookups import (
Exact,
GreaterThan,
@@ -9,7 +7,6 @@ from django.db.models.lookups import (
LessThan,
LessThanOrEqual,
)
-from django.utils.deprecation import RemovedInDjango50Warning
class MultiColSource:
@@ -45,14 +42,7 @@ def get_normalized_value(value, lhs):
if isinstance(value, Model):
if value.pk is None:
- # When the deprecation ends, replace with:
- # raise ValueError(
- # "Model instances passed to related filters must be saved."
- # )
- warnings.warn(
- "Passing unsaved model instances to related filters is deprecated.",
- RemovedInDjango50Warning,
- )
+ raise ValueError("Model instances passed to related filters must be saved.")
value_list = []
sources = lhs.output_field.path_infos[-1].target_fields
for source in sources:
diff --git a/docs/releases/5.0.txt b/docs/releases/5.0.txt
index e058f4a76c..a5c5916511 100644
--- a/docs/releases/5.0.txt
+++ b/docs/releases/5.0.txt
@@ -322,3 +322,5 @@ to remove usage of these features.
* The usage of ``QuerySet.iterator()`` on a queryset that prefetches related
objects without providing the ``chunk_size`` argument is no longer allowed.
+
+* Passing unsaved model instances to related filters is no longer allowed.
diff --git a/tests/queries/tests.py b/tests/queries/tests.py
index a6a2b252eb..9578777b11 100644
--- a/tests/queries/tests.py
+++ b/tests/queries/tests.py
@@ -13,8 +13,7 @@ from django.db.models.functions import ExtractYear, Length, LTrim
from django.db.models.sql.constants import LOUTER
from django.db.models.sql.where import AND, OR, NothingNode, WhereNode
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
-from django.test.utils import CaptureQueriesContext, ignore_warnings, register_lookup
-from django.utils.deprecation import RemovedInDjango50Warning
+from django.test.utils import CaptureQueriesContext, register_lookup
from .models import (
FK1,
@@ -1956,16 +1955,13 @@ class Queries5Tests(TestCase):
self.assertEqual(authors.count(), 1)
def test_filter_unsaved_object(self):
- # These tests will catch ValueError in Django 5.0 when passing unsaved
- # model instances to related filters becomes forbidden.
- # msg = "Model instances passed to related filters must be saved."
- msg = "Passing unsaved model instances to related filters is deprecated."
+ msg = "Model instances passed to related filters must be saved."
company = Company.objects.create(name="Django")
- with self.assertWarnsMessage(RemovedInDjango50Warning, msg):
+ with self.assertRaisesMessage(ValueError, msg):
Employment.objects.filter(employer=Company(name="unsaved"))
- with self.assertWarnsMessage(RemovedInDjango50Warning, msg):
+ with self.assertRaisesMessage(ValueError, msg):
Employment.objects.filter(employer__in=[company, Company(name="unsaved")])
- with self.assertWarnsMessage(RemovedInDjango50Warning, msg):
+ with self.assertRaisesMessage(ValueError, msg):
StaffUser.objects.filter(staff=Staff(name="unsaved"))
@@ -3327,28 +3323,14 @@ class ExcludeTests(TestCase):
[self.j1, self.j2],
)
- @ignore_warnings(category=RemovedInDjango50Warning)
- def test_exclude_unsaved_o2o_object(self):
- jack = Staff.objects.create(name="jack")
- jack_staff = StaffUser.objects.create(staff=jack)
- unsaved_object = Staff(name="jane")
-
- self.assertIsNone(unsaved_object.pk)
- self.assertSequenceEqual(
- StaffUser.objects.exclude(staff=unsaved_object), [jack_staff]
- )
-
def test_exclude_unsaved_object(self):
- # These tests will catch ValueError in Django 5.0 when passing unsaved
- # model instances to related filters becomes forbidden.
- # msg = "Model instances passed to related filters must be saved."
company = Company.objects.create(name="Django")
- msg = "Passing unsaved model instances to related filters is deprecated."
- with self.assertWarnsMessage(RemovedInDjango50Warning, msg):
+ msg = "Model instances passed to related filters must be saved."
+ with self.assertRaisesMessage(ValueError, msg):
Employment.objects.exclude(employer=Company(name="unsaved"))
- with self.assertWarnsMessage(RemovedInDjango50Warning, msg):
+ with self.assertRaisesMessage(ValueError, msg):
Employment.objects.exclude(employer__in=[company, Company(name="unsaved")])
- with self.assertWarnsMessage(RemovedInDjango50Warning, msg):
+ with self.assertRaisesMessage(ValueError, msg):
StaffUser.objects.exclude(staff=Staff(name="unsaved"))