summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2024-04-08 18:10:14 +0200
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2024-04-10 15:55:30 +0200
commitf075a19e856ced33ddfb0e1330b5c277ddb14bfe (patch)
treee0ca7652dbcdfde69eb70c4add312b8e128d59d9
parent58061fd2b4c4b66c0fd3db8026c8b5e369ed9ec3 (diff)
[5.0.x] Fixed #35350 -- Fixed save() with pk set on models with GeneratedFields.
Thanks Matt Hegarty for the report and Simon Charette and Natalia Bidart for the reviews. Regression in f333e35. Backport of 8b53560eea9f10a1271d3bdf765dc6f969c7d9d5 from main.
-rw-r--r--django/db/models/base.py12
-rw-r--r--docs/releases/5.0.5.txt4
-rw-r--r--tests/model_fields/test_generatedfield.py6
3 files changed, 17 insertions, 5 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 8b15932e45..9cb1cfa8e6 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -993,12 +993,16 @@ class Model(AltersData, metaclass=ModelBase):
for a single table.
"""
meta = cls._meta
- non_pks = [f for f in meta.local_concrete_fields if not f.primary_key]
+ non_pks_non_generated = [
+ f
+ for f in meta.local_concrete_fields
+ if not f.primary_key and not f.generated
+ ]
if update_fields:
- non_pks = [
+ non_pks_non_generated = [
f
- for f in non_pks
+ for f in non_pks_non_generated
if f.name in update_fields or f.attname in update_fields
]
@@ -1030,7 +1034,7 @@ class Model(AltersData, metaclass=ModelBase):
None,
(getattr(self, f.attname) if raw else f.pre_save(self, False)),
)
- for f in non_pks
+ for f in non_pks_non_generated
]
forced_update = update_fields or force_update
updated = self._do_update(
diff --git a/docs/releases/5.0.5.txt b/docs/releases/5.0.5.txt
index fd36171c40..506127b0ca 100644
--- a/docs/releases/5.0.5.txt
+++ b/docs/releases/5.0.5.txt
@@ -9,4 +9,6 @@ Django 5.0.5 fixes several bugs in 5.0.4.
Bugfixes
========
-* ...
+* Fixed a bug in Django 5.0 that caused a crash of ``Model.save()`` when
+ creating an instance of a model with a ``GeneratedField`` and providing a
+ primary key (:ticket:`35350`).
diff --git a/tests/model_fields/test_generatedfield.py b/tests/model_fields/test_generatedfield.py
index 641ce591e4..2fbfe3c82a 100644
--- a/tests/model_fields/test_generatedfield.py
+++ b/tests/model_fields/test_generatedfield.py
@@ -207,6 +207,12 @@ class GeneratedFieldTestMixin:
m.refresh_from_db()
self.assertEqual(m.field, 8)
+ def test_save_model_with_pk(self):
+ m = self.base_model(pk=1, a=1, b=2)
+ m.save()
+ m = self._refresh_if_needed(m)
+ self.assertEqual(m.field, 3)
+
def test_save_model_with_foreign_key(self):
fk_object = Foo.objects.create(a="abc", d=Decimal("12.34"))
m = self.base_model(a=1, b=2, fk=fk_object)