From 0fcd72bc48eade21ce9202d7a71692f9b5a42bd2 Mon Sep 17 00:00:00 2001 From: Aman Pandey Date: Mon, 27 Nov 2023 23:21:33 +0530 Subject: [PATCH] Fixed #34633 -- Made create() method of reverse many-to-one managers clear prefetch_related() cache. --- django/db/models/fields/related_descriptors.py | 1 + docs/ref/models/querysets.txt | 1 + tests/many_to_one/tests.py | 8 ++++++++ 3 files changed, 10 insertions(+) diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py index 46a5823647d..f5a81ab49c0 100644 --- a/django/db/models/fields/related_descriptors.py +++ b/django/db/models/fields/related_descriptors.py @@ -840,6 +840,7 @@ def create_reverse_many_to_one_manager(superclass, rel): def create(self, **kwargs): self._check_fk_val() + self._remove_prefetched_objects() kwargs[self.field.name] = self.instance db = router.db_for_write(self.model, instance=self.instance) return super(RelatedManager, self.db_manager(db)).create(**kwargs) diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 9f2a4178810..b9f263f7090 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -1259,6 +1259,7 @@ database. Also, if you call the database-altering methods :meth:`~django.db.models.fields.related.RelatedManager.add`, + :meth:`~django.db.models.fields.related.RelatedManager.create`, :meth:`~django.db.models.fields.related.RelatedManager.remove`, :meth:`~django.db.models.fields.related.RelatedManager.clear` or :meth:`~django.db.models.fields.related.RelatedManager.set`, on diff --git a/tests/many_to_one/tests.py b/tests/many_to_one/tests.py index b07972ec311..ac5b35e055b 100644 --- a/tests/many_to_one/tests.py +++ b/tests/many_to_one/tests.py @@ -800,6 +800,14 @@ class ManyToOneTests(TestCase): # refs #21563 self.assertFalse(hasattr(Article(), "reporter")) + def test_create_after_prefetch(self): + c = City.objects.create(name="Musical City") + d1 = District.objects.create(name="Ladida", city=c) + city = City.objects.prefetch_related("districts").get(id=c.id) + self.assertSequenceEqual(city.districts.all(), [d1]) + d2 = city.districts.create(name="Goa") + self.assertSequenceEqual(city.districts.all(), [d1, d2]) + def test_clear_after_prefetch(self): c = City.objects.create(name="Musical City") d = District.objects.create(name="Ladida", city=c)