DevGang
Авторизоваться

Сигналы в Django

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

В django у нас есть два объекта, один из которых является отправителем, а другой - получателем, отправитель отправит сигнал о любом конкретном событии, и все получатели, которые прослушивают это событие, уведомляются сигналом и выполняют определенные действия.

Сигналы на основе моделей Django

Давайте рассмотрим несколько примеров с использованием встроенных сигналов django.

Определим несколько моделей в django models.py

models.py
from django.db import models
from django.contrib.auth.models import User
import datetime

# Create your models here.
class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    profile_url = models.URLField()
    mobile = models.CharField(max_length=20, default='999-999-9999')
    funds = models.FloatField(default=2000)

    def __str__(self):
        return "[PROFILE]:" + self.user.username


class Log(models.Model):
    timestamp = models.DateTimeField(default=datetime.datetime.now)
    message = models.TextField()

    def __str__(self):
        return self.message

Здесь мы определили профиль двух моделей, который расширяет встроенную модель пользователя models.OneToOneField, а другая - модель Log, которая просто используется для хранения сообщений журнала в базе данных.

Теперь давайте определим reveiver, который использует сигнал post_save, который срабатывает после сохранения конкретной модели в базе данных.

models.py
# .... models defined above

from django.db.models.signals import post_save
from django.dispatch import receiver


# triggred when User object is created
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(
            user=instance
        )

# triggred when User object is saved
@receiver(post_save, sender=User)
def log_user_saved(sender, instance, **kwargs):
    Log.objects.create(
        message=f"user {instance.username} is saved"
    )

# triggred when Profile object is saved
@receiver(post_save, sender=Profile)
def log_profile_saved(sender, instance, **kwargs):
    Log.objects.create(
        message=f"profile {instance} is saved"
    )

Как вы можете видеть выше, мы создали 3 функции приемника, давайте посмотрим на каждую из них.

create_profile этот приемник срабатывает, когда генерируется сигнал post_save для модели пользователя, т. е. после того, как модель пользователя была сохранена в базе данных, модель пользователя генерирует сигнал post_save, и срабатывает приемник create_profile

в create_profile мы создаем профиль для пользователя, мы можем проверить это, перейдя к панели администратора django и создав пользователя

Создание пользователя

Пользователь изменен

Профиль создан

Как мы видим на изображении выше, профиль создается автоматически для пользователя с помощью сигнала post_save

Аналогично, если мы перейдем к модели журнала, мы увидим журналы, созданные для каждого сигнала.

на изображении выше мы видим, что объекты журнала создаются при срабатывании сигнала пользователя и профиля.

аналогично post_save у нас есть такие сигналы, как pre_save, pre_delete, post_delete, pre_init, post_init, m2m_changed

Приемник работает с различными сигналами

pre_init

receiver_function(sender, *args, **kwargs)

post_init

receiver_function(sender, instance)

pre_save

receiver_function(sender, instance, raw, using, update_fields)

post_save

receiver_function(sender, instance, created, raw, using, update_fields)

pre_delete

receiver_function(sender, instance, using)

post_delete

receiver_function(sender, instance, using)

m2m_changed

receiver_function(sender, instance, action, reverse, model, pk_set, using)
#Python
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В подарок 100$ на счет при регистрации

Получить