[4.1.x] Fixed #33952 -- Reallowed creating reverse foreign key managers on unsaved instances.
Thanks Claude Paroz for the report. Regression in7ba6ebe914
. Backport of806e9e2d0d
from main
This commit is contained in:
parent
0890719402
commit
fca055315e
|
@ -627,15 +627,6 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
||||||
|
|
||||||
self.core_filters = {self.field.name: instance}
|
self.core_filters = {self.field.name: instance}
|
||||||
|
|
||||||
# Even if this relation is not to pk, we require still pk value.
|
|
||||||
# The wish is that the instance has been already saved to DB,
|
|
||||||
# although having a pk value isn't a guarantee of that.
|
|
||||||
if self.instance.pk is None:
|
|
||||||
raise ValueError(
|
|
||||||
f"{instance.__class__.__name__!r} instance needs to have a primary "
|
|
||||||
f"key value before this relationship can be used."
|
|
||||||
)
|
|
||||||
|
|
||||||
def __call__(self, *, manager):
|
def __call__(self, *, manager):
|
||||||
manager = getattr(self.model, manager)
|
manager = getattr(self.model, manager)
|
||||||
manager_class = create_reverse_many_to_one_manager(manager.__class__, rel)
|
manager_class = create_reverse_many_to_one_manager(manager.__class__, rel)
|
||||||
|
@ -700,6 +691,14 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
||||||
pass # nothing to clear from cache
|
pass # nothing to clear from cache
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
# Even if this relation is not to pk, we require still pk value.
|
||||||
|
# The wish is that the instance has been already saved to DB,
|
||||||
|
# although having a pk value isn't a guarantee of that.
|
||||||
|
if self.instance.pk is None:
|
||||||
|
raise ValueError(
|
||||||
|
f"{self.instance.__class__.__name__!r} instance needs to have a "
|
||||||
|
f"primary key value before this relationship can be used."
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
return self.instance._prefetched_objects_cache[
|
return self.instance._prefetched_objects_cache[
|
||||||
self.field.remote_field.get_cache_name()
|
self.field.remote_field.get_cache_name()
|
||||||
|
|
|
@ -49,3 +49,6 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed a regression in Django 4.1 that caused an incorrect migration when
|
* Fixed a regression in Django 4.1 that caused an incorrect migration when
|
||||||
renaming a model with ``ManyToManyField`` and ``db_table`` (:ticket:`33953`).
|
renaming a model with ``ManyToManyField`` and ``db_table`` (:ticket:`33953`).
|
||||||
|
|
||||||
|
* Reallowed, following a regression in Django 4.1, creating reverse foreign key
|
||||||
|
managers on unsaved instances (:ticket:`33952`).
|
||||||
|
|
|
@ -748,6 +748,9 @@ class ManyToOneTests(TestCase):
|
||||||
)
|
)
|
||||||
with self.assertRaisesMessage(ValueError, msg):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
th.child_set.count()
|
th.child_set.count()
|
||||||
|
# The reverse foreign key manager can be created.
|
||||||
|
self.assertEqual(th.child_set.model, Third)
|
||||||
|
|
||||||
th.save()
|
th.save()
|
||||||
# Now the model is saved, so we will need to execute a query.
|
# Now the model is saved, so we will need to execute a query.
|
||||||
with self.assertNumQueries(1):
|
with self.assertNumQueries(1):
|
||||||
|
|
Loading…
Reference in New Issue