RestrictedError
Исключение RestrictedError выбрасывается при попытке удаления объекта модели, который защищён через внешний ключ с параметром on_delete=models.PROTECT. Это исключение является подклассом IntegrityError и используется для предотвращения случайного удаления данных, на которые есть зависимости в других таблицах. Оно возникает только в том случае, когда существуют связанные записи, ссылающиеся на удаляемый объект.
Синтаксис
from django.db.models.deletion import RestrictedError
try:
obj.delete()
except RestrictedError as e:
# Обработка ошибки
print(e)
Пример . Модель
Рассмотрим модели Category и Article, где категория защищена от удаления, если на неё ссылаются статьи:
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Article(models.Model):
title = models.CharField(max_length=200)
category = models.ForeignKey(
Category,
on_delete=models.PROTECT,
related_name='articles'
)
def __str__(self):
return self.title
Пример . Возникновение исключения
Попробуем удалить категорию, которая содержит связанные статьи:
from myapp.models import Category, Article
# Создаём категорию и статью
category = Category.objects.create(name='Technology')
Article.objects.create(title='Django Basics', category=category)
# Пытаемся удалить категорию
try:
category.delete()
except RestrictedError as e:
print(f"Error: {e}")
Результат выполнения кода:
"Error: Cannot delete category 'Technology' because it has protected related objects: Article: Django Basics"
Обработка исключения с получением связанных объектов
Исключение RestrictedError содержит информацию о защищённых объектах, которые мешают удалению:
from myapp.models import Category, Article
category = Category.objects.get(name='Technology')
try:
category.delete()
except RestrictedError as e:
# Получаем защищённые объекты
protected_objects = e.protected_objects
print(f"Protected objects: {protected_objects}")
# Можно вывести информацию о каждом объекте
for obj in protected_objects:
print(f" - {obj}")
Результат выполнения кода:
"Protected objects: [<Article: Django Basics>]"
" - Django Basics"
Обход исключения через каскадное удаление
Если необходимо удалить категорию вместе со всеми статьями, нужно изменить параметр on_delete на models.CASCADE:
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=100)
class Article(models.Model):
title = models.CharField(max_length=200)
category = models.ForeignKey(
Category,
on_delete=models.CASCADE,
related_name='articles'
)
Теперь удаление категории будет удалять все связанные статьи:
from myapp.models import Category, Article
category = Category.objects.get(name='Technology')
# Удаляем категорию со всеми статьями
deleted_count = category.delete()
print(f"Deleted {deleted_count} objects")
Результат выполнения кода:
"Deleted (2, {'myapp.Article': 1, 'myapp.Category': 1})"
Смотрите также
-
исключение
ProtectedError,
которое возникает при попытке удалить объект с защищёнными связями -
исключение
IntegrityError,
базовое исключение для ошибок целостности базы данных -
исключение
DoesNotExist,
которое возникает при отсутствии запрашиваемого объекта -
исключение
ObjectDoesNotExist,
базовое исключение для всехDoesNotExistошибок моделей