Что такое сигнал post_save в Django и когда его следует использовать

Ответ

post_save — это сигнал в фреймворке Django, который отправляется сразу после того, как метод save() модели успешно завершил свою работу и данные были сохранены в базу данных. Это часть встроенной системы сигналов, позволяющей выполнять определенные действия в ответ на события, происходящие в приложении.

Использование сигналов, таких как post_save, позволяет отделить логику, не связанную напрямую с сохранением модели, и реализовать принцип слабой связанности (low coupling) компонентов системы.

Принцип работы:

Вы создаете функцию-обработчик (receiver), которая будет вызываться каждый раз, когда сигнал post_save срабатывает для указанной модели (sender).

Основной пример:

Предположим, мы хотим автоматически создавать профиль пользователя (UserProfile) каждый раз, когда создается новый пользователь (User).

# myapp/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from .models import UserProfile

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    """Обработчик сигнала для создания профиля."""
    if created:
        # Аргумент 'created' равен True только при первом сохранении
        UserProfile.objects.create(user=instance)

# myapp/apps.py
from django.apps import AppConfig

class MyappConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'myapp'

    def ready(self):
        import myapp.signals # Важно импортировать сигналы здесь

Ключевые аргументы обработчика:

  • sender: Класс модели, который отправил сигнал (в примере — User).
  • instance: Конкретный экземпляр модели, который был сохранен.
  • created: Булево значение. True, если в базе данных была создана новая запись (эквивалентно INSERT). False, если запись была обновлена (UPDATE).

Частые сценарии использования:

  • Создание связанных объектов (как в примере выше).
  • Денормализация данных или обновление агрегированных значений.
  • Инвалидация кэша при изменении данных.
  • Отправка уведомлений (например, по email) после создания или обновления объекта.