Skip to content

Commit

Permalink
Fixed #34743 -- Fixed Meta.constraints validation crash when using pk.
Browse files Browse the repository at this point in the history
Thanks Nwawel A Iroume for the report.
  • Loading branch information
panicofr authored and felixxm committed Aug 11, 2023
1 parent 9946f0b commit 1506f49
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
5 changes: 4 additions & 1 deletion django/db/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1235,11 +1235,14 @@ def _get_field_value_map(self, meta, exclude=None):
if exclude is None:
exclude = set()
meta = meta or self._meta
return {
field_map = {
field.name: Value(getattr(self, field.attname), field)
for field in meta.local_concrete_fields
if field.name not in exclude
}
if "pk" not in exclude:
field_map["pk"] = Value(self.pk, meta.pk)
return field_map

def prepare_database_save(self, field):
if self.pk is None:
Expand Down
2 changes: 1 addition & 1 deletion django/db/models/sql/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -1670,7 +1670,7 @@ def names_to_path(self, names, opts, allow_many=True, fail_on_missing=False):
path, names_with_path = [], []
for pos, name in enumerate(names):
cur_names_with_path = (name, [])
if name == "pk":
if name == "pk" and opts is not None:
name = opts.pk.name

field = None
Expand Down
13 changes: 13 additions & 0 deletions tests/constraints/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,19 @@ def test_validate_nullable_jsonfield(self):
is_not_null_constraint.validate(JSONFieldModel, JSONFieldModel(data=None))
is_not_null_constraint.validate(JSONFieldModel, JSONFieldModel(data={}))

def test_validate_pk_field(self):
constraint_with_pk = models.CheckConstraint(
check=~models.Q(pk=models.F("age")),
name="pk_not_age_check",
)
constraint_with_pk.validate(ChildModel, ChildModel(pk=1, age=2))
msg = f"Constraint “{constraint_with_pk.name}” is violated."
with self.assertRaisesMessage(ValidationError, msg):
constraint_with_pk.validate(ChildModel, ChildModel(pk=1, age=1))
with self.assertRaisesMessage(ValidationError, msg):
constraint_with_pk.validate(ChildModel, ChildModel(id=1, age=1))
constraint_with_pk.validate(ChildModel, ChildModel(pk=1, age=1), exclude={"pk"})


class UniqueConstraintTests(TestCase):
@classmethod
Expand Down

0 comments on commit 1506f49

Please sign in to comment.