Что такое сигналы в django
Сигналы ¶
Django включает в себя «диспетчер сигналов», который помогает развязанным приложениям получать уведомления, когда действия происходят где-то в другом месте во фреймворке. Вкратце, сигналы позволяют определенным отправителям уведомлять группу получателей о том, что произошло какое-то действие. Они особенно полезны, когда одни и те же события могут интересовать несколько фрагментов кода.
Отправляется при изменении ManyToManyField модели.
Отправляется, когда Django запускает или завершает HTTP-запрос.
Полный список и полное объяснение каждого сигнала см. Во встроенной документации по сигналам.
Прослушивание сигналов ¶
Чтобы получить сигнал, зарегистрируйте функцию приемника с помощью Signal.connect() метода. Функция приемника вызывается при отправке сигнала. Все функции приемника сигнала вызываются по очереди в том порядке, в котором они были зарегистрированы.
Давайте посмотрим, как это работает, зарегистрировав сигнал, который вызывается после завершения каждого HTTP-запроса. Будем подключаться к request_finished сигналу.
Функции приемника ¶
Во-первых, нам нужно определить функцию приемника. Приемником может быть любая функция или метод Python:
Обратите внимание, что функция принимает sender аргумент вместе с ключевым словом arguments ( **kwargs ); все обработчики сигналов должны принимать эти аргументы.
Подключение функций ресивера ¶
Есть два способа подключить приемник к сигналу. Вы можете выбрать маршрут подключения вручную:
Как вариант, вы можете использовать receiver() декоратор:
Вот как вы связываетесь с декоратором:
Теперь наша my_callback функция будет вызываться каждый раз при завершении запроса.
Где должен жить этот код?
Строго говоря, код обработки сигналов и регистрации может находиться где угодно, хотя рекомендуется избегать корневого модуля приложения и его models модуля, чтобы минимизировать побочные эффекты импорта кода.
Подключение к сигналам, отправляемым определенными отправителями ¶
В этих случаях вы можете зарегистрироваться для получения сигналов, отправленных только определенными отправителями. В случае django.db.models.signals.pre_save отправителя будет сохраняемый класс модели, поэтому вы можете указать, что вам нужны только сигналы, отправляемые некоторой моделью:
Разные сигналы используют разные объекты в качестве отправителей; вам необходимо обратиться к документации по встроенным сигналам для получения подробной информации о каждом конкретном сигнале.
Предотвращение дублирования сигналов ¶
В некоторых случаях код подключения приемников к сигналам может выполняться несколько раз. Это может привести к тому, что ваша функция приемника будет зарегистрирована более одного раза и, следовательно, будет вызываться столько раз для события сигнала. Например, ready() во время тестирования метод может выполняться более одного раза. В общем, это происходит везде, где ваш проект импортирует модуль, в котором вы определяете сигналы, потому что регистрация сигнала выполняется столько раз, сколько импортировано.
Если такое поведение проблематично (например, при использовании сигналов для отправки электронной почты при сохранении модели), передайте уникальный идентификатор в качестве dispatch_uid аргумента для идентификации функции получателя. Этот идентификатор обычно представляет собой строку, хотя любого хешируемого объекта будет достаточно. Конечным результатом является то, что ваша функция приемника будет привязана к сигналу только один раз для каждого уникального dispatch_uid значения:
Определение и отправка сигналов ¶
Ваши приложения могут использовать инфраструктуру сигналов и предоставлять свои собственные сигналы.
Когда использовать собственные сигналы
Сигналы ¶
Список всех сигналов, которые отправляет Django. Все встроенные сигналы отправляются с использованием send() метода.
См. Документацию по диспетчеру сигналов для получения информации о том, как регистрироваться и получать сигналы.
Сигналы модели ¶
Многие из этих сигналов отправляются различными методами модели, такими как __init__() или save() которые вы можете переопределить в своем собственном коде.
Если вы переопределите эти методы в своей модели, вы должны вызвать методы родительского класса для отправки этих сигналов.
pre_init ¶
Аргументы, отправленные с этим сигналом:
Например, в учебнике есть такая строка:
Аргументы, отправленные pre_init обработчику, будут следующими:
Аргумент | Значение |
---|---|
sender | Question (сам класс) |
args | [] (пустой список, потому что не были переданы позиционные аргументы __init__() ) |
kwargs |
post_init ¶
Подобно pre_init, но этот отправляется, когда __init__() метод завершается.
Аргументы, отправленные с этим сигналом:
sender Как указано выше: класс модели, для которого только что был создан экземпляр. instance
Фактический экземпляр только что созданной модели.
pre_save ¶
Аргументы, отправленные с этим сигналом:
post_save ¶
Аргументы, отправленные с этим сигналом:
pre_delete ¶
Аргументы, отправленные с этим сигналом:
sender Класс модели. instance Фактический удаляемый экземпляр. using Используемый псевдоним базы данных.
post_delete ¶
Аргументы, отправленные с этим сигналом:
sender Класс модели. instance
Фактический удаляемый экземпляр.
Обратите внимание, что объекта больше не будет в базе данных, поэтому будьте очень осторожны с этим экземпляром.
using Используемый псевдоним базы данных.
m2m_changed ¶
Аргументы, отправленные с этим сигналом:
Строка, указывающая тип обновления, которое выполняется для отношения. Это может быть одно из следующих:
«pre_add» Отправляется перед добавлением в отношение одного или нескольких объектов. «post_add» Отправляется после добавления в отношение одного или нескольких объектов. «pre_remove» Отправляется до того, как один или несколько объектов будут удалены из отношения. «post_remove» Отправляется после удаления одного или нескольких объектов из отношения. «pre_clear» Отправлено до того, как связь будет очищена. «post_clear» Отправляется после очистки связи. reverse Указывает, какая сторона отношения обновляется (т. Е. Изменяется ли это прямое или обратное отношение). model Класс объектов, которые добавляются, удаляются или удаляются из отношения. pk_set
using Используемый псевдоним базы данных.
Например, если a Pizza может иметь несколько Topping объектов, смоделированных следующим образом:
Если бы мы подключили такой обработчик:
а потом сделал что-то вроде этого:
аргументы, отправленные m2m_changed обработчику ( toppings_changed в приведенном выше примере), будут:
И если бы мы тогда сделали что-то вроде этого:
аргументы, отправленные m2m_changed обработчику, будут следующими:
class_prepared ¶
Отправляется всякий раз, когда класс модели был «подготовлен», то есть после того, как модель была определена и зарегистрирована в модельной системе Django. Django использует этот сигнал для внутренних целей; он обычно не используется в сторонних приложениях.
Аргументы, которые отправляются с этим сигналом:
sender Класс модели, который только что был подготовлен.
Управляющие сигналы ¶
pre_migrate ¶
Отправляется migrate командой перед началом установки приложения. Он не выдается для приложений, в которых отсутствует models модуль.
Аргументы, отправленные с этим сигналом:
Функции, которые прослушивают, pre_migrate должны настраивать то, что они выводят на экран, в зависимости от значения этого аргумента.
post_migrate ¶
Отправляется в конце migrate (даже если миграции не выполняются) и flush команд. Он не выдается для приложений, в которых отсутствует models модуль.
Обработчики этого сигнала не должны выполнять изменения схемы базы данных, поскольку это может привести flush к сбою команды, если она выполняется во время выполнения migrate команды.
Аргументы, отправленные с этим сигналом:
Функции, которые прослушивают, post_migrate должны настраивать то, что они выводят на экран, в зависимости от значения этого аргумента.
Например, вы можете зарегистрировать обратный вызов AppConfig следующим образом:
Сигналы запроса / ответа ¶
Сигналы, отправляемые основной структурой при обработке запроса.
request_started ¶
Отправляется, когда Django начинает обрабатывать HTTP-запрос.
Аргументы, отправленные с этим сигналом:
sender Класс обработчика, например, django.core.handlers.wsgi.WsgiHandler который обработал запрос. environ environ Словарь предоставляется на запрос.
request_finished ¶
Отправляется, когда Django завершает доставку HTTP-ответа клиенту.
Аргументы, отправленные с этим сигналом:
sender Класс обработчика, как указано выше.
got_request_exception ¶
Этот сигнал отправляется всякий раз, когда Django обнаруживает исключение при обработке входящего HTTP-запроса.
Аргументы, отправленные с этим сигналом:
sender Не используется (всегда None ). request HttpRequest Объект.
Тестовые сигналы ¶
setting_changed ¶
Этот сигнал отправляется, когда значение параметра изменяется через django.test.TestCase.settings() диспетчер контекста или django.test.override_settings() декоратор / диспетчер контекста.
Фактически он отправляется дважды: когда применяется новое значение («настройка») и когда восстанавливается исходное значение («удаление»). Используйте enter аргумент, чтобы различать их.
Вы также можете импортировать этот сигнал из, django.core.signals чтобы избежать импорта из django.test не тестовых ситуаций.
Аргументы, отправленные с этим сигналом:
template_rendered ¶
Аргументы, отправленные с этим сигналом:
Оболочки базы данных ¶
Сигналы, отправляемые оболочкой базы данных при инициировании соединения с базой данных.
connection_created ¶
Отправляется, когда оболочка базы данных устанавливает первоначальное соединение с базой данных. Это особенно полезно, если вы хотите отправлять какие-либо команды подключения к серверу SQL.
Сигналы¶
Django includes a «signal dispatcher» which helps decoupled applications get notified when actions occur elsewhere in the framework. In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place. They’re especially useful when many pieces of code may be interested in the same events.
Отправляется при изменении ManyToManyField на модели.
Отправляется, когда Django начинает или завершает HTTP-запрос.
Прослушивание сигналов¶
Функции приемника¶
Во-первых, нам нужно определить функцию-приемник. Приемником может быть любая функция или метод Python:
Подключение функций приемника¶
Существует два способа подключения приемника к сигналу. Можно воспользоваться ручным способом подключения:
В качестве альтернативы можно использовать декоратор receiver() :
receiver ( signal ) [исходный код] ¶
Параметры: | signal – Сигнал или список сигналов, к которым подключается функция. |
---|
Вот как вы связываетесь с декоратором:
Теперь наша функция my_callback будет вызываться каждый раз, когда запрос завершается.
Где этот код должен находится?
Подключение к сигналам, посылаемым определенными отправителями¶
В этих случаях вы можете зарегистрироваться для получения сигналов, отправленных только определенными отправителями. В случае django.db.models.signals.pre_save отправителем будет класс сохраняемой модели, поэтому вы можете указать, что хотите получать сигналы, посылаемые только некоторой моделью:
Различные сигналы используют различные объекты в качестве отправителей; вам нужно обратиться к built-in signal documentation для получения подробной информации о каждом конкретном сигнале.
Предотвращение дублирования сигналов¶
In some circumstances, the code connecting receivers to signals may run multiple times. This can cause your receiver function to be registered more than once, and thus called as many times for a signal event. For example, the ready() method may be executed more than once during testing. More generally, this occurs everywhere your project imports the module where you define the signals, because signal registration runs as many times as it is imported.
Если такое поведение проблематично (например, при использовании сигналов для отправки электронного письма при каждом сохранении модели), передайте уникальный идентификатор в качестве аргумента dispatch_uid для идентификации вашей функции-приемника. Обычно этот идентификатор представляет собой строку, хотя подойдет и любой хэшируемый объект. В итоге ваша функция-приемник будет привязана к сигналу только один раз для каждого уникального значения dispatch_uid :
Определение и отправка сигналов¶
Ваши приложения могут использовать преимущества сигнальной инфраструктуры и предоставлять собственные сигналы.
Когда использовать пользовательские сигналы
Документация Django 1.8
Django содержит “диспетчер сигналов”, который позволяет одним приложениям фреймворка получать уведомления от других после того, как в последних произойдут некоторые события. Вкратце, сигналы позволяют определённым отправителям уведомлять некоторый набор получателей о совершении действий. Сигналы особенно полезны, когда поведение многих фрагментов кода зависит от инициации одних и тех же событий.
Django предоставляет набор встроенных сигналов, которые позволяют пользовательскому коду получать уведомление от Django об определённых событиях. Эти сигналы включают в себя некоторые полезные уведомления:
Отправляются, когда Django начинает или заканчивает HTTP запрос.
Полный список этих сигналов, а также описание каждого сигнала, см. в документации по встроенным сигналам.
Вы можете также определять и посылать свои собственные сигналы; см. ниже.
Прослушивание сигналов¶
Функции-получатели¶
Во-первых, мы должны определить функцию-получатель. Получатель должен быть Python функцией или методом:
Это было бы неверно – на самом деле, Django выдаст ошибку, если Вы это сделаете. Так произойдёт, потому что при любом вызове аргументы могут быть добавлены к сигналу и получатель должен быть в состоянии обработать эти новые аргументы.
Регистрация функции-получателя¶
Есть два способа, которыми Вы можете подключить получатель к сигналу. Вы можете вручную вызвать connect:
receiver(signal)¶
Параметры: | signal – Сигнал или список обрабатываемых сигналов. |
---|
Вот как можно использовать декоратор:
Теперь наша функция my_callback будет вызываться каждый раз, когда запрос завершается.
Куда положить этот код?
Сигналы, получаемые от определённых отправителей.¶
Отправителями различных сигналов могут быть различные объекты. Для получения детальной информации по каждому такому сигналу обращайтесь к документации по встроенным сигналам.
Предотвращение дублирования сигналов¶
В некоторых случаях модуль, в котором Вы подключаете сигналы, может быть импортирован несколько раз. Это может привести к тому, что получатель сигнала будет зарегистрирован несколько раз, и таким образом, вызов сигнала произойдет несколько раз при наступлении одного и того же события.
Создание и посылка сигналов.¶
Вы можете создавать свои собственные сигналы в ваших приложениях.
Создание сигналов¶
Вы можете задать в этом списке аргументов любые значения передаваемых параметров.
Отправка сигналов¶
В Django существует два способа отправки сигналов.
Например, вот как может выглядеть отправка сигнала pizza_done :
send() отличается от send_robust() способом обработки исключений, генерируемых функцией-получателем. send() не ловит никаких исключений, сгенерированных в получателе, позволяя исключению проваливаться дальше. Таким образом, не все получатели могут получить сигнал при возникновении ошибки.
send_robust() перехватывает все ошибки, наследуемые от класса Exception языка Python, и гарантирует, что сигнал дойдёт до всех получателей. Если произойдёт ошибка в одном из них, экземпляр исключения будет помещён в кортежную пару, для получателя, который соответствует вызываемой ошибке.
Отключение сигнала¶
Было добавлено возвращение булева значения.
Русские Блоги
Сигналы в Django и их использование
Django обеспечивает «планирование сигналов» для разделения, когда фреймворк выполняет операции.
Когда происходят какие-то действия, система будет выполнять соответствующие операции в соответствии с функцией, определенной сигналом.
Встроенный сигнал в Django
Model_signals
Managemeng_signals
Request/response_signals
Test_signals
Datebase_Wrapperd
Для встроенных сигналов Django вам нужно только зарегистрировать указанный сигнал. Когда программа выполняет соответствующую операцию, система автоматически запускает функцию регистрации.
Пример, создание записи в базе данных, триггер pre_save с участием post_save сигнал
Создайте проект Django и настройте отображение маршрутизации
Проект __init__.py Код в файле:
Создайте index.html Веб-страницу, откройте этот проект в браузере и распечатайте информацию на стороне сервера следующим образом:
Сравнивая распечатанные результаты, вы можете увидеть, что после сохранения объекта модели он содержит «create=True» Пара «ключ-значение».
Вы также можете использовать декоратор для запуска сигнала, поместив указанное выше __init__.py Модификация кода в:
Затем функция обратного вызова автоматически запускается после завершения этого запроса в фоновом режиме. «request finished» Это предложение.
Пользовательский сигнал
1. Определите сигнал
Создайте новый проект, настройте маршрутизацию и создайте проект в корневом каталоге проекта. singal_test.py Файл с содержимым
2. Зарегистрируйте сигнал
Заявка на проект ниже __init__.py содержание документа:
3. Триггерный сигнал
Просмотр содержимого функции:
Открыть в браузере index.html Веб-страница, информация о фоновой печати выглядит следующим образом:
Поскольку триггер встроенного сигнала был интегрирован в Django, он будет вызываться автоматически, а для пользовательских сигналов его нужно запускать в любой позиции.