Исключение ValidationError

Исключение ValidationError применяется для сообщения об ошибках валидации данных в Django. Оно обычно возникает при проверке данных модели или формы, когда переданные значения не соответствуют заданным правилам валидации. Исключение может быть выброшено в методах clean, clean_<field_name>, а также в пользовательских валидаторах.

ValidationError принимает несколько типов аргументов: строку с сообщением об ошибке, словарь с ошибками для разных полей или список сообщений. Оно также может содержать параметр code для категоризации ошибок и параметр params для динамической подстановки значений в сообщение.

Синтаксис

pythonfrom django.core.exceptions import ValidationError

raise ValidationError(message, code=None, params=None)

Пример . С моделью

Рассмотрим модель Article с пользовательской валидацией в методе clean:

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

class Article(models.Model):
  title = models.CharField(max_length=100)
  status = models.CharField(max_length=20, default='draft')
  content = models.TextField()

  def clean(self):
    if self.status == 'published' and len(self.content) < 100:
      raise ValidationError(
        'Published article must have at least 100 characters',
        code='content_too_short'
      )

    if len(self.title) > 50:
      raise ValidationError(
        'Title cannot exceed 50 characters',
        code='title_too_long'
      )

Пример . С формой

Использование ValidationError в методах валидации формы:

pythonfrom django import forms
from django.core.exceptions import ValidationError

class ArticleForm(forms.Form):
  title = forms.CharField(max_length=100)
  content = forms.CharField(widget=forms.Textarea)

  def clean_title(self):
    title = self.cleaned_data['title']
    if 'django' not in title.lower():
      raise ValidationError(
        'Title must contain the word "django"',
        code='missing_keyword'
      )
    return title

  def clean(self):
    cleaned_data = super().clean()
    title = cleaned_data.get('title')
    content = cleaned_data.get('content')

    if title and content:
      if len(content) < len(title) * 2:
        raise ValidationError(
          'Content must be at least twice as long as title',
          code='content_too_short'
        )

Пример . С обработкой исключения

Перехват и обработка ValidationError при сохранении модели:

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

article = Article(
  title='Hello Django',
  status='published',
  content='Short content'
)

try:
  article.full_clean()
  article.save()
except ValidationError as e:
  print(f"Validation error: {e.message}")
  print(f"Error code: {e.code}")
  if hasattr(e, 'error_dict'):
    for field, errors in e.error_dict.items():
      for error in errors:
        print(f"{field}: {error.message}")

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

python"Validation error: Published article must have at least 100 characters"
"Error code: content_too_short"

Пример . Со списком ошибок

Использование списка сообщений для нескольких ошибок:

pythonfrom django.core.exceptions import ValidationError

errors = [
  'Title is required',
  'Content is too short',
  'Status must be either draft or published'
]

raise ValidationError(errors)

Пример . Со словарем ошибок

Передача словаря с ошибками для разных полей:

pythonfrom django.core.exceptions import ValidationError

error_dict = {
  'title': [
    'Title cannot be empty',
    'Title must contain at least 3 characters'
  ],
  'content': ['Content cannot be empty']
}

raise ValidationError(error_dict)

Пример . С параметром params

Использование параметра params для динамических сообщений:

pythonfrom django.core.exceptions import ValidationError

class ArticleValidator:
  def validate_title_length(self, title):
    min_length = 10
    if len(title) < min_length:
      raise ValidationError(
        'Title must be at least %(min_length)d characters long',
        code='title_too_short',
        params={'min_length': min_length}
      )

validator = ArticleValidator()
try:
  validator.validate_title_length('Hello')
except ValidationError as e:
  print(e.message)
  print(f"Minimum length: {e.params['min_length']}")

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

python"Title must be at least 10 characters long"
"Minimum length: 10"

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

  • исключение IntegrityError,
    которое возникает при нарушении целостности базы данных
  • исключение DoesNotExist,
    которое возникает при попытке получить несуществующий объект
  • исключение MultipleObjectsReturned,
    которое возникает при получении более одного объекта
  • исключение Http404,
    которое возникает при запросе несуществующей страницы