РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
491 of 818 menu

Исключение ProtectedError

Исключение ProtectedError относится к модулю django.db.models и возникает при попытке удаления объекта модели, если на него ссылаются другие объекты через внешний ключ с установленным параметром on_delete в значение PROTECT. Это исключение наследуется от django.db.IntegrityError. При возникновении исключения в атрибуте protected_objects содержится список объектов, которые препятствуют удалению.

Синтаксис

from django.db.models import PROTECT from django.db import models class ParentModel(models.Model): name = models.CharField(max_length=100) class ChildModel(models.Model): parent = models.ForeignKey( ParentModel, on_delete=PROTECT ) title = models.CharField(max_length=100)

Пример . Возникновение исключения

Рассмотрим модели блога, где категория защищена от удаления, если на неё ссылаются статьи:

from django.db import models from django.db.models import PROTECT class Category(models.Model): name = models.CharField(max_length=100) class Article(models.Model): title = models.CharField(max_length=100) category = models.ForeignKey( Category, on_delete=PROTECT ) content = models.TextField()

Попытка удалить категорию, к которой привязаны статьи, приведёт к возникновению исключения:

from myapp.models import Category, Article category = Category.objects.get(id=1) articles = Article.objects.filter(category=category) print(f"Articles in category: {articles.count()}") category.delete()

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

"Articles in category: 3" "django.db.models.deletion.ProtectedError: Cannot delete some instances of model 'Category' because they are referenced through protected foreign keys: 'Article.category'"

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

Исключение можно перехватить и обработать, чтобы корректно сообщить пользователю о невозможности удаления:

from django.db.models.deletion import ProtectedError from myapp.models import Category try: category = Category.objects.get(name="Technology") category.delete() print("Category deleted successfully") except ProtectedError as e: print("Cannot delete category with related objects:") for obj in e.protected_objects: print(f"- {obj} (ID: {obj.id})")

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

"Cannot delete category with related objects:" "- Article: Django Basics (ID: 1)" "- Article: Python Web (ID: 2)" "- Article: Database Design (ID: 3)"

Пример . С несколькими защищёнными связями

Если модель имеет несколько защищённых внешних ключей, то при удалении возникнет исключение с указанием всех препятствующих объектов:

from django.db import models from django.db.models import PROTECT class User(models.Model): username = models.CharField(max_length=100) class Post(models.Model): title = models.CharField(max_length=100) author = models.ForeignKey( User, on_delete=PROTECT, related_name="posts" ) class Comment(models.Model): text = models.TextField() post = models.ForeignKey( Post, on_delete=PROTECT, related_name="comments" ) user = models.ForeignKey( User, on_delete=PROTECT, related_name="comments" )

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

from django.db.models.deletion import ProtectedError from myapp.models import User try: user = User.objects.get(username="john_doe") user.delete() except ProtectedError as e: print(f"Protected objects: {e.protected_objects}")

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

"Protected objects: [<Post: Django Tutorial>, <Comment: Great post!>]"

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

  • исключение IntegrityError,
    базовое исключение для всех ошибок целостности данных
  • исключение RestrictedError,
    возникающее при попытке удаления с ограничениями
  • исключение DoesNotExist,
    возникающее при отсутствии запрашиваемого объекта
  • исключение ObjectDoesNotExist,
    базовое исключение для отсутствующих объектов модели
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить