1
0
mirror of https://github.com/django/django.git synced 2025-05-30 18:56:32 +00:00

Fixed #34319 -- Fixed Model.validate_constraints() crash on ValidationError with no code.

Thanks Mateusz Kurowski for the report.

Regression in 667105877e6723c6985399803a364848891513cc.
This commit is contained in:
Mariusz Felisiak 2023-02-08 16:38:55 +01:00 committed by GitHub
parent 69069a443a
commit 2fd755b361
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 3 deletions

View File

@ -1444,7 +1444,10 @@ class Model(AltersData, metaclass=ModelBase):
try: try:
constraint.validate(model_class, self, exclude=exclude, using=using) constraint.validate(model_class, self, exclude=exclude, using=using)
except ValidationError as e: except ValidationError as e:
if e.code == "unique" and len(constraint.fields) == 1: if (
getattr(e, "code", None) == "unique"
and len(constraint.fields) == 1
):
errors.setdefault(constraint.fields[0], []).append(e) errors.setdefault(constraint.fields[0], []).append(e)
else: else:
errors = e.update_error_dict(errors) errors = e.update_error_dict(errors)

View File

@ -12,4 +12,5 @@ in 4.1.6.
Bugfixes Bugfixes
======== ========
* ... * Fixed a bug in Django 4.1 that caused a crash of model validation on
``ValidationError`` with no ``code`` (:ticket:`34319`).

View File

@ -3,7 +3,7 @@ from unittest import mock
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import IntegrityError, connection, models from django.db import IntegrityError, connection, models
from django.db.models import F from django.db.models import F
from django.db.models.constraints import BaseConstraint from django.db.models.constraints import BaseConstraint, UniqueConstraint
from django.db.models.functions import Lower from django.db.models.functions import Lower
from django.db.transaction import atomic from django.db.transaction import atomic
from django.test import SimpleTestCase, TestCase, skipIfDBFeature, skipUnlessDBFeature from django.test import SimpleTestCase, TestCase, skipIfDBFeature, skipUnlessDBFeature
@ -589,6 +589,26 @@ class UniqueConstraintTests(TestCase):
with self.assertRaisesMessage(ValidationError, msg): with self.assertRaisesMessage(ValidationError, msg):
UniqueConstraintConditionProduct(name=obj2.name).validate_constraints() UniqueConstraintConditionProduct(name=obj2.name).validate_constraints()
def test_model_validation_constraint_no_code_error(self):
class ValidateNoCodeErrorConstraint(UniqueConstraint):
def validate(self, model, instance, **kwargs):
raise ValidationError({"name": ValidationError("Already exists.")})
class NoCodeErrorConstraintModel(models.Model):
name = models.CharField(max_length=255)
class Meta:
constraints = [
ValidateNoCodeErrorConstraint(
Lower("name"),
name="custom_validate_no_code_error",
)
]
msg = "{'name': ['Already exists.']}"
with self.assertRaisesMessage(ValidationError, msg):
NoCodeErrorConstraintModel(name="test").validate_constraints()
def test_validate(self): def test_validate(self):
constraint = UniqueConstraintProduct._meta.constraints[0] constraint = UniqueConstraintProduct._meta.constraints[0]
msg = "Unique constraint product with this Name and Color already exists." msg = "Unique constraint product with this Name and Color already exists."