Метод validate_unique
Метод validate_unique применяется к экземпляру модели и проверяет,
что значения полей соответствуют ограничениям уникальности,
заданным в модели через параметры unique, unique_together
или UniqueConstraint. Метод автоматически вызывается во время
выполнения full_clean, но может быть вызван и отдельно для
явной проверки уникальности.
В параметры метода передаются:
-
exclude- список имен полей, которые следует исключить из проверки уникальности
Если проверка не пройдена, метод возбуждает исключение
ValidationError с информацией о полях, нарушивших
ограничения уникальности.
Синтаксис
instance.validate_unique(exclude=None)
Пример
Создадим модель с полем, имеющим ограничение уникальности, и проверим работу метода:
from 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)
Результат выполнения кода:
"Validation passed"
Пример
Попробуем создать объект с неуникальным значением поля:
from 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)
Результат выполнения кода:
{"name": ["Category with this Name already exists."]}
Пример
Рассмотрим модель с составной уникальностью через параметр
UniqueConstraint и проверим работу метода:
from 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)
Результат выполнения кода:
"Validation passed"
Пример
Метод validate_unique вызывается автоматически при
использовании full_clean. Рассмотрим этот вариант:
from 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)
Результат выполнения кода:
"All validations passed"
Пример
Используем параметр exclude для исключения полей
из проверки уникальности:
from 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)
Результат выполнения кода:
"Validation with exclude passed"
Пример
Рассмотрим ситуацию, когда несколько полей имеют ограничения уникальности и одно из них нарушается:
from 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)
Результат выполнения кода:
{"email": ["Employee with this Email already exists."]}
Смотрите также
-
метод
clean,
который выполняет валидацию модели на уровне полей -
метод
full_clean,
который вызывает все методы валидации модели -
метод
clean_fields,
который проверяет отдельные поля модели -
метод
validate_constraints,
который проверяет ограничения базы данных