Django сигналы

Django сигналы

Добрый день, гики!!!

Сигналы в django - это способ для ваших моделей общаться друг с другом при наступлении события. Те, кто работал с JavaScript, скорее всего, сталкивались с методом .addEventListener(), который вызывается только при наступлении события. Этот метод работает так же, как и сигналы django, но на этот раз он вызывается, когда одна часть двух связанных моделей сохраняется, удаляется, обновляется и т.д.

Ниже перечислены некоторые из доступных событий, которые могут быть вызваны.

  • pre_save и post_save: Эти события вызываются перед сохранением модели и после сохранения модели соответственно.
  • pre_delete и post_delete: Эти события вызываются до или после удаления модели соответственно.
  • m2m_changed: Вызывается при изменении поля "многие ко многим" в модели.
  • request_started и request_finished: Вызываются до и после того, как HTTP-запрос будет отправлен или завершен соответственно.

Создание рабочего сигнала

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

Я буду считать, что вы уже знаете, как начать проект django, поэтому я пропущу эту часть. Перейдите в файл models.py вашего приложения и создайте модель Profile.

from django.contrib.auth import get_user_model
import uuid

# user object
User = get_user_model()


class Profile(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    friends = models.ManyToManyField("self", blank=True)
    picture = models.ImageField(upload_to="dps")

    def __str__(self):
        return self.user.username


Хорошо! Мы настроили нашу модель профиля, давайте сделаем миграции и мигрируем в базу данных

$ python manage.py makemigrations
$ python manage.py migrate

Теперь мы хотим, чтобы профили автоматически создавались при создании экземпляра пользователя. Для этого создайте файл в каталоге вашего приложения и назовите его signals.py

#signals.py

from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Profile, User

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
        print(f"Profile for {instance.username} created successfully!!")

Здесь я использовал сигнал post_save, потому что наш профиль будет создан после успешного создания пользователя.

Нам нужно сообщить нашему приложению об этом файле, поэтому перейдите к вашему файлу apps.py, который был создан, когда вы выполнили $ python manage.py startapp , и добавьте в него этот фрагмент кода.

class AccountConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name="account"

    # add this
    def ready(self):
        from . import signals

Теперь все готово. Чтобы это работало, убедитесь, что ваше приложение зарегистрировано в INSTALLED_APPS как <имяприложения>.apps.<имяприложения>Config.

Теперь вы можете создавать экземпляры профилей просто на лету. Спасибо, что прочитали, оставляйте комментарии ниже. До встречи в следующем выпуске.