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

Сигнал post_delete

Сигнал post_delete отправляется автоматически после того, как объект модели был успешно удален из базы данных. Сигнал полезен для выполнения дополнительных действий, таких как удаление связанных файлов, очистка кэша, отправка уведомлений или ведение журнала аудита. Важно отметить, что сигнал срабатывает даже при каскадном удалении через связь ForeignKey с параметром on_delete=models.CASCADE.

Сигнал принимает несколько аргументов: sender - класс модели, которая была удалена; instance - экземпляр удаляемого объекта (важно: объект еще существует в памяти, но уже удален из БД); using - псевдоним базы данных; origin - источник удаления (добавлен в Django 3.2). Сигнал работает в рамках транзакции, поэтому если транзакция будет откатана, изменения, внесенные в обработчике, также будут отменены.

Синтаксис

from django.db.models.signals import post_delete from django.dispatch import receiver @receiver(post_delete, sender=MyModel) def my_handler(sender, instance, **kwargs): # Your logic here pass

Пример

Рассмотрим модель Article, которая хранит файлы изображений. При удалении статьи необходимо также удалить файл из файловой системы:

from django.db import models from django.db.models.signals import post_delete from django.dispatch import receiver import os class Article(models.Model): title = models.CharField(max_length=100) image = models.ImageField(upload_to='articles/') created_at = models.DateTimeField(auto_now_add=True) @receiver(post_delete, sender=Article) def delete_article_image(sender, instance, **kwargs): # Delete the image file from filesystem if instance.image and os.path.isfile(instance.image.path): os.remove(instance.image.path) print(f"Deleted image: {instance.image.path}")

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

"Deleted image: /media/articles/photo_2025.jpg"

Пример

Рассмотрим использование сигнала для логирования удалений. Создадим модель LogEntry, которая будет хранить информацию о всех удаленных записях:

from django.db import models from django.db.models.signals import post_delete from django.dispatch import receiver from django.utils.timezone import now class Product(models.Model): name = models.CharField(max_length=100) price = models.DecimalField(max_digits=10, decimal_places=2) stock = models.IntegerField() class DeletionLog(models.Model): model_name = models.CharField(max_length=100) object_id = models.IntegerField() object_repr = models.CharField(max_length=200) deleted_at = models.DateTimeField(auto_now_add=True) @receiver(post_delete, sender=Product) def log_product_deletion(sender, instance, **kwargs): DeletionLog.objects.create( model_name='Product', object_id=instance.id, object_repr=str(instance), deleted_at=now() ) print(f"Logged deletion of product: {instance.name}")

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

"Logged deletion of product: Laptop"

Пример

Рассмотрим работу сигнала с каскадным удалением. При удалении категории, все связанные с ней статьи должны быть удалены, и сигнал сработает для каждого удаленного объекта:

from django.db import models from django.db.models.signals import post_delete from django.dispatch import receiver class Category(models.Model): name = models.CharField(max_length=50) class Post(models.Model): title = models.CharField(max_length=100) category = models.ForeignKey(Category, on_delete=models.CASCADE) @receiver(post_delete, sender=Post) def post_deleted_handler(sender, instance, **kwargs): print(f"Post '{instance.title}' was deleted") @receiver(post_delete, sender=Category) def category_deleted_handler(sender, instance, **kwargs): print(f"Category '{instance.name}' was deleted") # Deleting category triggers post_delete for each related Post category = Category.objects.get(id=1) category.delete()

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

"Post 'Django Basics' was deleted" "Post 'Advanced Django' was deleted" "Category 'Programming' was deleted"

Пример

Рассмотрим использование сигнала для обновления статистики. При удалении статьи уменьшаем счетчик общего количества статей:

from django.db import models from django.db.models.signals import post_delete from django.dispatch import receiver class Author(models.Model): name = models.CharField(max_length=50) articles_count = models.IntegerField(default=0) class Article(models.Model): title = models.CharField(max_length=100) author = models.ForeignKey(Author, on_delete=models.CASCADE) @receiver(post_delete, sender=Article) def update_author_stats(sender, instance, **kwargs): author = instance.author author.articles_count -= 1 author.save() print(f"Updated articles count for {author.name}: {author.articles_count}")

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

"Updated articles count for John Doe: 4"

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

  • сигнал pre_delete,
    который срабатывает перед удалением объекта
  • сигнал post_save,
    который отправляется после сохранения объекта
  • сигнал pre_save,
    который срабатывает перед сохранением объекта
  • метод delete,
    который удаляет объект из базы данных
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить