Fixed #34743 -- Fixed Meta.constraints validation crash when using pk.

Thanks Nwawel A Iroume for the report.
This commit is contained in:
Francesco Panico 2023-08-10 14:08:11 +00:00 committed by Mariusz Felisiak
parent 9946f0b0d9
commit 1506f498fe
3 changed files with 18 additions and 2 deletions

View File

@ -1235,11 +1235,14 @@ class Model(AltersData, metaclass=ModelBase):
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:

View File

@ -1670,7 +1670,7 @@ class Query(BaseExpression):
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

View File

@ -352,6 +352,19 @@ class CheckConstraintTests(TestCase):
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