Метод validate_unique

Метод validate_unique применяется к экземпляру модели и проверяет, что значения полей соответствуют ограничениям уникальности, заданным в модели через параметры unique, unique_together или UniqueConstraint. Метод автоматически вызывается во время выполнения full_clean, но может быть вызван и отдельно для явной проверки уникальности.

В параметры метода передаются:

Если проверка не пройдена, метод возбуждает исключение ValidationError с информацией о полях, нарушивших ограничения уникальности.

Синтаксис

pythoninstance.validate_unique(exclude=None)

Пример

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

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

class Category(models.Model):
  name = models.CharField(max_length=50, unique=True)

category = Category(name="Technology")

try:
  category.validate_unique()
  print("Validation passed")
except ValidationError as e:
  print(e.message_dict)

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

python"Validation passed"

Пример

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

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

class Category(models.Model):
  name = models.CharField(max_length=50, unique=True)

# Сначала создаем запись в БД
Category.objects.create(name="Technology")

# Пытаемся создать дубликат
new_category = Category(name="Technology")

try:
  new_category.validate_unique()
except ValidationError as e:
  print(e.message_dict)

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

python{"name": ["Category with this Name already exists."]}

Пример

Рассмотрим модель с составной уникальностью через параметр UniqueConstraint и проверим работу метода:

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

class Article(models.Model):
  title = models.CharField(max_length=100)
  author = models.CharField(max_length=50)
  
  class Meta:
    constraints = [
      models.UniqueConstraint(
        fields=["title", "author"],
        name="unique_title_author"
      )
    ]

article = Article(title="Django Tutorial", author="John")

try:
  article.validate_unique()
  print("Validation passed")
except ValidationError as e:
  print(e.message_dict)

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

python"Validation passed"

Пример

Метод validate_unique вызывается автоматически при использовании full_clean. Рассмотрим этот вариант:

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

class User(models.Model):
  username = models.CharField(max_length=30, unique=True)
  email = models.EmailField()

user = User(username="admin", email="admin@example.com")

try:
  # full_clean автоматически вызывает validate_unique
  user.full_clean()
  print("All validations passed")
except ValidationError as e:
  print(e.message_dict)

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

python"All validations passed"

Пример

Используем параметр exclude для исключения полей из проверки уникальности:

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

class Product(models.Model):
  code = models.CharField(max_length=20, unique=True)
  name = models.CharField(max_length=100)

product = Product(code="PRD001", name="Laptop")

try:
  # Исключаем поле code из проверки
  product.validate_unique(exclude=["code"])
  print("Validation with exclude passed")
except ValidationError as e:
  print(e.message_dict)

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

python"Validation with exclude passed"

Пример

Рассмотрим ситуацию, когда несколько полей имеют ограничения уникальности и одно из них нарушается:

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

class Employee(models.Model):
  employee_id = models.CharField(max_length=10, unique=True)
  email = models.EmailField(unique=True)
  name = models.CharField(max_length=50)

# Создаем существующего сотрудника
Employee.objects.create(
  employee_id="EMP001",
  email="john@example.com",
  name="John"
)

# Пытаемся создать сотрудника с существующим email
new_employee = Employee(
  employee_id="EMP002",
  email="john@example.com",
  name="Jane"
)

try:
  new_employee.validate_unique()
except ValidationError as e:
  print(e.message_dict)

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

python{"email": ["Employee with this Email already exists."]}

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

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