Метод validate_constraints

Метод validate_constraints применяется к экземпляру модели и выполняет проверку всех ограничений (constraints), определенных в классе модели. В отличие от метода full_clean, который проверяет типы полей и их значения, данный метод фокусируется исключительно на ограничениях базы данных, таких как уникальность, проверочные условия и составные ограничения. Метод выбрасывает исключение ValidationError в случае нарушения любого из ограничений.

Синтаксис

pythoninstance.validate_constraints(exclude=None, using=DEFAULT_DB_ALIAS)

Параметр exclude позволяет указать список полей, которые следует исключить из проверки. Параметр using определяет базу данных, для которой выполняется проверка ограничений.

Пример . С ограничением уникальности

Рассмотрим модель статьи с уникальным ограничением на заголовок:

pythonfrom django.db import models
from django.core.exceptions import ValidationError

class Article(models.Model):
  title = models.CharField(max_length=100)
  content = models.TextField()

  class Meta:
    constraints = [
      models.UniqueConstraint(
        fields=['title'],
        name='unique_article_title'
      )
    ]

Попробуем создать две статьи с одинаковым заголовком:

pythonfrom myapp.models import Article

# Creating first article
article1 = Article(title="First Article", content="Content 1")
article1.save()

# Creating second article with same title
article2 = Article(title="First Article", content="Content 2")

try:
  article2.validate_constraints()
except ValidationError as e:
  print(e.message_dict)

Результат выполнения кода:

python{'__all__': ['Article with this Title already exists.']}

Пример . С проверочным ограничением

Создадим модель с ограничением, которое проверяет, что возраст пользователя находится в допустимом диапазоне:

pythonfrom django.db import models
from django.core.exceptions import ValidationError

class UserProfile(models.Model):
  username = models.CharField(max_length=50)
  age = models.IntegerField()

  class Meta:
    constraints = [
      models.CheckConstraint(
        check=models.Q(age__gte=18) & models.Q(age__lte=100),
        name='age_range_check'
      )
    ]

Попробуем создать пользователя с некорректным возрастом:

pythonfrom myapp.models import UserProfile
from django.core.exceptions import ValidationError

# Creating user with invalid age
user = UserProfile(username="john_doe", age=15)

try:
  user.validate_constraints()
except ValidationError as e:
  print(e.message_dict)

Результат выполнения кода:

python{'__all__': ['Check constraint "age_range_check" is violated.']}

Пример . С составным ограничением

Создадим модель, где комбинация полей должна быть уникальной:

pythonfrom django.db import models
from django.core.exceptions import ValidationError

class Subscription(models.Model):
  user = models.CharField(max_length=50)
  service = models.CharField(max_length=50)
  status = models.CharField(max_length=20)

  class Meta:
    constraints = [
      models.UniqueConstraint(
        fields=['user', 'service'],
        name='unique_user_service_subscription'
      )
    ]

Проверим, как метод реагирует на дублирующиеся пары "пользователь-услуга":

pythonfrom myapp.models import Subscription
from django.core.exceptions import ValidationError

# Creating first subscription
sub1 = Subscription(
  user="alice",
  service="premium",
  status="active"
)
sub1.save()

# Creating duplicate subscription
sub2 = Subscription(
  user="alice",
  service="premium",
  status="pending"
)

try:
  sub2.validate_constraints()
except ValidationError as e:
  print(e.message_dict)

Результат выполнения кода:

python{'__all__': ['Subscription with this User and Service already exists.']}

Пример . С исключением полей

Параметр exclude позволяет пропустить проверку определенных полей:

pythonfrom myapp.models import Article
from django.core.exceptions import ValidationError

# Creating article that would violate constraint
article = Article(title="First Article", content="New content")

# Excluding title from validation
try:
  article.validate_constraints(exclude=['title'])
  print("Validation passed for excluded field")
except ValidationError as e:
  print(e.message_dict)

Результат выполнения кода:

python"Validation passed for excluded field"

Смотрите также

  • метод clean_fields,
    который выполняет валидацию отдельных полей модели
  • метод clean,
    который выполняет пользовательскую валидацию модели
  • метод full_clean,
    который выполняет полную валидацию модели
  • метод validate_unique,
    который проверяет уникальность полей модели