mirror of
https://github.com/django/django.git
synced 2025-10-28 08:06:09 +00:00
[5.0.x] Fixed #35638 -- Updated validate_constraints to consider db_default.
Backport of 509763c799 from main.
This commit is contained in:
committed by
Sarah Boyce
parent
e88ef6a27d
commit
333cfab512
@@ -4,7 +4,7 @@ from django.core.exceptions import ValidationError
|
||||
from django.db import IntegrityError, connection, models
|
||||
from django.db.models import F
|
||||
from django.db.models.constraints import BaseConstraint, UniqueConstraint
|
||||
from django.db.models.functions import Abs, Lower
|
||||
from django.db.models.functions import Abs, Lower, Upper
|
||||
from django.db.transaction import atomic
|
||||
from django.test import SimpleTestCase, TestCase, skipIfDBFeature, skipUnlessDBFeature
|
||||
from django.test.utils import ignore_warnings
|
||||
@@ -14,6 +14,7 @@ from .models import (
|
||||
ChildModel,
|
||||
ChildUniqueConstraintProduct,
|
||||
JSONFieldModel,
|
||||
ModelWithDatabaseDefault,
|
||||
Product,
|
||||
UniqueConstraintConditionProduct,
|
||||
UniqueConstraintDeferrable,
|
||||
@@ -365,6 +366,47 @@ class CheckConstraintTests(TestCase):
|
||||
constraint_with_pk.validate(ChildModel, ChildModel(id=1, age=1))
|
||||
constraint_with_pk.validate(ChildModel, ChildModel(pk=1, age=1), exclude={"pk"})
|
||||
|
||||
@skipUnlessDBFeature("supports_json_field")
|
||||
def test_validate_jsonfield_exact(self):
|
||||
data = {"release": "5.0.2", "version": "stable"}
|
||||
json_exact_constraint = models.CheckConstraint(
|
||||
check=models.Q(data__version="stable"),
|
||||
name="only_stable_version",
|
||||
)
|
||||
json_exact_constraint.validate(JSONFieldModel, JSONFieldModel(data=data))
|
||||
|
||||
data = {"release": "5.0.2", "version": "not stable"}
|
||||
msg = f"Constraint “{json_exact_constraint.name}” is violated."
|
||||
with self.assertRaisesMessage(ValidationError, msg):
|
||||
json_exact_constraint.validate(JSONFieldModel, JSONFieldModel(data=data))
|
||||
|
||||
def test_database_default(self):
|
||||
models.CheckConstraint(
|
||||
check=models.Q(field_with_db_default="field_with_db_default"),
|
||||
name="check_field_with_db_default",
|
||||
).validate(ModelWithDatabaseDefault, ModelWithDatabaseDefault())
|
||||
|
||||
# Ensure that a check also does not silently pass with either
|
||||
# FieldError or DatabaseError when checking with a db_default.
|
||||
with self.assertRaises(ValidationError):
|
||||
models.CheckConstraint(
|
||||
check=models.Q(
|
||||
field_with_db_default="field_with_db_default", field="field"
|
||||
),
|
||||
name="check_field_with_db_default_2",
|
||||
).validate(
|
||||
ModelWithDatabaseDefault, ModelWithDatabaseDefault(field="not-field")
|
||||
)
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
models.CheckConstraint(
|
||||
check=models.Q(field_with_db_default="field_with_db_default"),
|
||||
name="check_field_with_db_default",
|
||||
).validate(
|
||||
ModelWithDatabaseDefault,
|
||||
ModelWithDatabaseDefault(field_with_db_default="other value"),
|
||||
)
|
||||
|
||||
|
||||
class UniqueConstraintTests(TestCase):
|
||||
@classmethod
|
||||
@@ -1220,3 +1262,30 @@ class UniqueConstraintTests(TestCase):
|
||||
msg = "A unique constraint must be named."
|
||||
with self.assertRaisesMessage(ValueError, msg):
|
||||
models.UniqueConstraint(fields=["field"])
|
||||
|
||||
def test_database_default(self):
|
||||
models.UniqueConstraint(
|
||||
fields=["field_with_db_default"], name="unique_field_with_db_default"
|
||||
).validate(ModelWithDatabaseDefault, ModelWithDatabaseDefault())
|
||||
models.UniqueConstraint(
|
||||
Upper("field_with_db_default"),
|
||||
name="unique_field_with_db_default_expression",
|
||||
).validate(ModelWithDatabaseDefault, ModelWithDatabaseDefault())
|
||||
|
||||
ModelWithDatabaseDefault.objects.create()
|
||||
|
||||
msg = (
|
||||
"Model with database default with this Field with db default already "
|
||||
"exists."
|
||||
)
|
||||
with self.assertRaisesMessage(ValidationError, msg):
|
||||
models.UniqueConstraint(
|
||||
fields=["field_with_db_default"], name="unique_field_with_db_default"
|
||||
).validate(ModelWithDatabaseDefault, ModelWithDatabaseDefault())
|
||||
|
||||
msg = "Constraint “unique_field_with_db_default_expression” is violated."
|
||||
with self.assertRaisesMessage(ValidationError, msg):
|
||||
models.UniqueConstraint(
|
||||
Upper("field_with_db_default"),
|
||||
name="unique_field_with_db_default_expression",
|
||||
).validate(ModelWithDatabaseDefault, ModelWithDatabaseDefault())
|
||||
|
||||
Reference in New Issue
Block a user