1
0
mirror of https://github.com/django/django.git synced 2025-03-06 07:22:32 +00:00

Refs #36075 -- Adjusted MTI handling of _non_pk_concrete_field_names.

Regression in bf7b17d16d3978b2e1cee4a0f7ce8840bd1a8dc4.

Thanks Sage Abdullah for the report.
This commit is contained in:
Simon Charette 2025-01-13 22:04:33 -05:00 committed by Sarah Boyce
parent 161e79d277
commit f07360e808
4 changed files with 21 additions and 8 deletions

View File

@ -874,13 +874,13 @@ class Model(AltersData, metaclass=ModelBase):
update_fields = frozenset(update_fields)
field_names = self._meta._non_pk_concrete_field_names
non_model_fields = update_fields.difference(field_names)
not_updatable_fields = update_fields.difference(field_names)
if non_model_fields:
if not_updatable_fields:
raise ValueError(
"The following fields do not exist in this model, are m2m "
"fields, or are non-concrete fields: %s"
% ", ".join(non_model_fields)
"fields, primary keys, or are non-concrete fields: %s"
% ", ".join(not_updatable_fields)
)
# If saving to the same database, and this model is deferred, then

View File

@ -1008,8 +1008,11 @@ class Options:
Return a set of the non-pk concrete field names defined on the model.
"""
names = []
all_pk_fields = set(self.pk_fields)
for parent in self.all_parents:
all_pk_fields.update(parent._meta.pk_fields)
for field in self.concrete_fields:
if field not in self.pk_fields:
if field not in all_pk_fields:
names.append(field.name)
if field.name != field.attname:
names.append(field.attname)

View File

@ -74,7 +74,7 @@ class CompositePKUpdateTests(TestCase):
def test_update_fields_pk_field(self):
msg = (
"The following fields do not exist in this model, are m2m fields, "
"or are non-concrete fields: id"
"primary keys, or are non-concrete fields: id"
)
with self.assertRaisesMessage(ValueError, msg):
self.user_1.save(update_fields=["id"])

View File

@ -7,8 +7,8 @@ from .models import Account, Employee, Person, Profile, ProxyEmployee
class UpdateOnlyFieldsTests(TestCase):
msg = (
"The following fields do not exist in this model, are m2m fields, or "
"are non-concrete fields: %s"
"The following fields do not exist in this model, are m2m "
"fields, primary keys, or are non-concrete fields: %s"
)
def test_update_fields_basic(self):
@ -308,3 +308,13 @@ class UpdateOnlyFieldsTests(TestCase):
profile_boss = Profile.objects.create(name="Boss", salary=3000)
with self.assertRaisesMessage(ValueError, self.msg % "non_concrete"):
profile_boss.save(update_fields=["non_concrete"])
def test_update_pk_field(self):
person_boss = Person.objects.create(name="Boss", gender="F")
with self.assertRaisesMessage(ValueError, self.msg % "id"):
person_boss.save(update_fields=["id"])
def test_update_inherited_pk_field(self):
employee_boss = Employee.objects.create(name="Boss", gender="F")
with self.assertRaisesMessage(ValueError, self.msg % "id"):
employee_boss.save(update_fields=["id"])