From c9ff757a55392b1f50968eb89fe775f6155168d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sedl=C3=A1k?= Date: Mon, 27 Jul 2026 15:18:33 +0530 Subject: [PATCH 1/3] Fixed #37234 -- Fixed bulk_create() for late-saved related primary keys. Objects with a primary key supplied by a late-saved related instance were partitioned before their related fields were prepared. This caused an assertion failure on backends returning rows from bulk inserts. Regression in 7d9aab8da0a06787d649762a702e1a518d843a63. --- django/db/models/query.py | 2 +- docs/releases/6.0.8.txt | 5 ++++- tests/bulk_create/tests.py | 7 +++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index 2d9bcee9bc96..748a0508b2ee 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -747,6 +747,7 @@ async def acreate(self, **kwargs): def _prepare_for_bulk_create(self, objs): objs_with_pk, objs_without_pk = [], [] for obj in objs: + obj._prepare_related_fields_for_save(operation_name="bulk_create") if isinstance(obj.pk, DatabaseDefault): objs_without_pk.append(obj) elif obj._is_pk_set(): @@ -757,7 +758,6 @@ def _prepare_for_bulk_create(self, objs): objs_with_pk.append(obj) else: objs_without_pk.append(obj) - obj._prepare_related_fields_for_save(operation_name="bulk_create") return objs_with_pk, objs_without_pk def _check_bulk_create_options( diff --git a/docs/releases/6.0.8.txt b/docs/releases/6.0.8.txt index 4f05b218da02..8ce8e50f5308 100644 --- a/docs/releases/6.0.8.txt +++ b/docs/releases/6.0.8.txt @@ -11,4 +11,7 @@ bugs in 6.0.7. Bugfixes ======== -* ... +* Fixed a regression in Django 6.0 that caused + :meth:`~django.db.models.query.QuerySet.bulk_create` to crash on databases + that support returning rows from bulk inserts when a related object providing + the primary key was saved after assignment (:ticket:`37234`). diff --git a/tests/bulk_create/tests.py b/tests/bulk_create/tests.py index 397fcb9186c3..eaf4bc05083c 100644 --- a/tests/bulk_create/tests.py +++ b/tests/bulk_create/tests.py @@ -439,6 +439,13 @@ def test_nullable_fk_after_parent_bulk_create(self): child = NullableFields.objects.get(integer_field=88) self.assertEqual(child.auto_field, parent) + def test_pk_from_related_instance_saved_after_init(self): + country = Country(name="Syldavia", iso_two_letter="SW") + related = RelatedModel(country=country) + country.save() + RelatedModel.objects.bulk_create([related]) + self.assertEqual(related.country_id, country.pk) + def test_unsaved_parent(self): parent = NoFields() msg = ( From 5c4a36f81752025e1d8bd0eefafafd2206e02f10 Mon Sep 17 00:00:00 2001 From: Jacob Walls Date: Wed, 22 Jul 2026 18:40:03 -0400 Subject: [PATCH 2/3] Refs #28586 -- Added coverage for from_queryset's fetch mode in refresh_from_db(). --- tests/basic/tests.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/basic/tests.py b/tests/basic/tests.py index a81724b70f51..d8f95b43aac7 100644 --- a/tests/basic/tests.py +++ b/tests/basic/tests.py @@ -1099,3 +1099,24 @@ def test_refresh_overwrites_queryset_fields(self): with self.assertNumQueries(1): a.refresh_from_db(fields=["headline"], from_queryset=from_queryset) self.assertEqual(a.headline, headline) + + def test_refresh_copies_fetch_mode_from_plucked_instance(self): + a = Article.objects.create(pub_date=datetime.now()) + fa = FeaturedArticle.objects.fetch_mode(models.FETCH_PEERS).create(article=a) + + from_queryset = FeaturedArticle.objects.fetch_mode(models.RAISE).select_related( + "article" + ) + fa.refresh_from_db(from_queryset=from_queryset) + self.assertEqual(fa._state.fetch_mode, models.FETCH_PEERS) + self.assertEqual(fa.article._state.fetch_mode, models.RAISE) + + def test_refresh_ignores_fetch_mode_if_no_instance_plucked(self): + a = Article.objects.create(pub_date=datetime.now()) + fa = FeaturedArticle.objects.fetch_mode(models.FETCH_PEERS).create(article=a) + + # This queryset's fetch mode is not used because no fields are plucked. + from_queryset = FeaturedArticle.objects.fetch_mode(models.RAISE) + fa.refresh_from_db(from_queryset=from_queryset) + self.assertEqual(fa._state.fetch_mode, models.FETCH_PEERS) + self.assertEqual(fa.article._state.fetch_mode, models.FETCH_PEERS) From 274a1d494d11d87a1b767340d1f398f197810f93 Mon Sep 17 00:00:00 2001 From: anurag629 Date: Fri, 27 Feb 2026 00:15:13 +0530 Subject: [PATCH 3/3] Refs #12227 -- Added test for PREPEND_WWW redirect following in test client. --- tests/test_client/tests.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_client/tests.py b/tests/test_client/tests.py index 98f01827d0a7..cc66a157b0a5 100644 --- a/tests/test_client/tests.py +++ b/tests/test_client/tests.py @@ -908,6 +908,16 @@ def test_redirect_with_http_host(self): ) self.assertEqual(response.content, b"hostname2") + @override_settings(PREPEND_WWW=True, ALLOWED_HOSTS=["testserver", "www.testserver"]) + def test_prepend_www_follow_redirect(self): + response = self.client.get("/get_view/", follow=True) + self.assertRedirects( + response, + "http://www.testserver/get_view/", + status_code=301, + target_status_code=200, + ) + def test_external_redirect_without_trailing_slash(self): """ Client._handle_redirects() with an empty path.