Вам нужны сигналы Django прямо сейчас — вот почему

Вам нужны сигналы Django прямо сейчас — вот почему

5 марта 2023 г.

Познакомьтесь с Джейн, увлеченным разработчиком программного обеспечения, которому нравится создавать надежные и эффективные веб-приложения с помощью Django. В настоящее время Джейн работает над проектом, в котором ей нужно выполнить определенный фрагмент кода на основе определенных событий, происходящих в ее приложении.

Она слышала о сигналах Django, но не совсем понимает, что это такое и как они работают.

Сигналы Django — это мощный инструмент для выполнения кода на основе определенных событий в вашем приложении Django.

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

Это может быть полезно для автоматизации задач, таких как отправка электронных писем, обновление записей или регистрация данных, всякий раз, когда в вашем приложении происходит определенное событие. В этом руководстве мы рассмотрим процесс использования сигналов Django для выполнения кода на основе определенных событий в вашем приложении.

Знакомство с сигналами Django

Сигналы Django позволяют определенным отправителям уведомлять набор получателей о выполнении определенных действий. Сигналы отправляются отправителями с помощью метода Signal.send() и принимаются получателями с помощью декоратора @receiver.

В Django есть несколько встроенных сигналов, таких как pre_save, post_save, pre_delete и post_delete. Эти сигналы отправляются всякий раз, когда экземпляр модели сохраняется или удаляется. Вы также можете создавать собственные сигналы для своего приложения.

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

В следующем разделе мы более подробно рассмотрим, как Джейн может использовать сигналы Django в своем проекте для выполнения кода на основе определенных событий.

image

Создание приемника сигнала

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

Джейн работала над веб-приложением, позволяющим пользователям подписываться на различные информационные бюллетени в зависимости от их интересов. Всякий раз, когда пользователь подписывается на информационный бюллетень или отказывается от подписки, Джейн необходимо обновить профиль пользователя, чтобы отразить его выбор.

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

Первым шагом для Джейн является определение сигналов, которые будет использовать ее приложение. Она создает два сигнала, один для подписки и один для отказа от подписки, и дает им описательные имена: user_subscribed и user_unsubscribed.

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

# File: yourapp/signals.py
from django.dispatch import Signal

user_subscribed = Signal(providing_args=['user_email'])
user_unsubscribed = Signal(providing_args=['user_email'])

После того, как Джейн определила свои сигналы, ей нужно связать их с соответствующими функциями, которые будут выполняться всякий раз, когда срабатывает сигнал. Она создает две функции, subscribe_newsletter и unsubscribe_newsletter, которые будут обновлять профиль пользователя при каждой подписке или отказе от подписки.

# File: yourapp/signals.py
...
from django.dispatch import receiver

...
@receiver(user_subscribed)
def subscribe_newsletter(sender, **kwargs):
    user_email = kwargs['user_email']

    # Business logic
        # user = User.objects.get(email=user_email)
    # user.profile.subscriptions.add("my_newsletter")
        # user.profile.save()
    print(f"Subscribed {user_email} to our newsletter")

@receiver(user_unsubscribed)
def unsubscribe_newsletter(sender, **kwargs):
    user_email = kwargs['user_email']

    # Business logic
        # user = User.objects.get(email=user_email)
    # user.profile.subscriptions.remove("my_newsletter")
        # user.profile.save()
    print(f"Unsubscribed {user_email} from our newsletter")

# Connecting recievers & signals
user_subscribed.connect(subscribe_newsletter)
user_unsubscribed.connect(unsubscribe_newsletter)

В этом примере декоратор @receiver используется для регистрации функции subscribe_newsletter() в качестве получателя сигнала user_subscribed. Функция просто выводит его на консоль.

Используйте его в своих представлениях

image

Теперь Джейн может использовать эти сигналы в своем файле views.py.

from .signals import user_subscribed, user_unsubscribed
from django.http import HttpResponse

def subscribe(request):
    user_email = request.GET.get('user_email')
    if user_email is None:
        return HttpResponse("Please provide a user_email parameter in GET request.")
    else:
        user_subscribed.send(sender=request.user, user_email=user_email)
        return HttpResponse(f"Subscribed {user_email} to our newsletter.")

def unsubscribe(request):
    user_email = request.GET.get('user_email')
    if user_email is None:
        return HttpResponse("Please provide a user_email parameter in GET request.")
    else:
        user_unsubscribed.send(sender=request.user, user_email=user_email)
        return HttpResponse(f"Unsubscribed {user_email} from our newsletter.")

Имея свои сигналы и функции, Джейн теперь может использовать их в своем приложении всякий раз, когда пользователь подписывается или отказывается от подписки на информационный бюллетень. Ей просто нужно импортировать соответствующий сигнал и отправить его с соответствующими данными.

Чтобы это сработало…

В этой ситуации есть одна загвоздка: код еще не работает. Чтобы наш код работал должным образом, нам нужно импортировать наши сигналы в файл конфигурации нашего приложения — apps.py

from django.apps import AppConfig

class AccountsConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'accounts'

    def ready(self) -> None:
        import accounts.signals
                print("Signals connected")

В этом примере метод ready() импортирует модуль signals.py, который содержит наши сигналы. Затем он регистрирует сообщение о том, что приемник сигнала подключен.

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

image

Также см.

Вы также можете использовать встроенные сигналы модели, такие как pre-save.

from django.contrib.auth.models import User
from django.db.models.signals import pre_save

@receiver(pre_save, sender=User)
def user_created(sender, **kwargs):
    user = kwargs['instance']
        # Other business logic you might want to add...
    print(f"Creating user, {user}")

Документация Django всегда будет ресурсом номер 1 для дальнейшего изучения: https://docs.djangoproject.com/en/ 4.1/темы/сигналы/

Кроме того, это хорошая запись в блоге от simpleisbetterthancomplex, если вам нужен подробный обзор; а не вводный пост, подобный этому.

Заключение

Сигналы Django предоставляют мощный инструмент для выполнения кода на основе определенных событий в вашем приложении. Используя сигналы, вы можете сделать свой код модульным и организованным, что упростит его обслуживание и обновление в будущем.

Независимо от того, создаете ли вы простое веб-приложение или сложное корпоративное приложение, сигналы помогут вам упростить код и сделать процесс разработки более эффективным.

Удачного кодирования!


Также опубликовано здесь


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE