Я только начал внедрять слушателей сигналов в проект django. Пока понимаю, что это такое и как ими пользоваться. Мне трудно понять, куда мне их положить. В документации с сайта django сказано следующее:
Вы можете разместить код обработки сигнала и регистрационный код где угодно. Однако вам необходимо убедиться, что модуль, в котором он находится, импортируется на ранней стадии, чтобы обработка сигналов была зарегистрирована до отправки каких-либо сигналов. Это делает файл models.py вашего приложения хорошим местом для регистрации обработчиков сигналов.
Хотя это хорошее предложение, наличие в моем models.py не модельных классов или методов просто меня не так.
Итак, каковы лучшие практики / правила для хранения и регистрации обработчиков сигналов?
источник
Foo
которая является частьюfooapp
. Но приемник сигнала является расширением и находится в другом приложении (напримерotherapp
).Это было добавлено в документацию при выпуске Django 1.7 :
Лучше всего определять обработчики в handlers.py в подмодуле сигналов, например, в файле, который выглядит так:
yourapp / signal / handlers.py :
from django.db.models.signals import pre_save from django.dispatch import receiver from myapp.models import MyModel @receiver(pre_save, sender=MyModel) def my_handler(sender, **kwargs): pass
Лучшее место для регистрации обработчика сигнала - это AppConfig приложения, которое его определяет, с помощью метода ready () . Это будет выглядеть так:
yourapp / apps.py :
from django.apps import AppConfig class TasksConfig(AppConfig): name = 'tasks' verbose_name = "Tasks" def ready(self): import yourproject.yourapp.signals.handlers #noqa
Убедитесь, что вы загружаете свой AppConfig, указав его либо непосредственно в INSTALLED_APPS вашего settings.py, либо в
__init__
вашем приложении. См . Дополнительную информацию в документации по ready () .Примечание. Если вы предоставляете сигналы другим приложениям, чтобы они тоже слушали, поместите их в
__init__
модуль сигналов, например, в файл, который выглядит так:yourapp / сигналы / __ init__.py
import django.dispatch task_generate_pre_save = django.dispatch.Signal(providing_args=["task"])
Затем другое приложение может прослушивать ваш сигнал, импортировав и зарегистрировав его, например
from yourapp.signals import task_generate_pre_save
. Разделение ваших сигналов от ваших обработчиков сохраняет чистоту.Инструкция для Django 1.6:
Если вы все еще застряли на Django 1.6 или ниже, вы бы сделали то же самое (определите свои обработчики в yourapp / signal / handlers.py), но вместо использования AppConfig вы загрузили бы обработчики через __init__.py из ваше приложение, например, что-то вроде:
yourapp / __ init__.py
import signals
Это не так хорошо, как использование метода ready (), потому что он часто вызывает проблемы с циклическим импортом.
источник
__init__
импорт сигналов, не сработает для меня, поэтому мне интересно, есть ли другое место, из которого я мог бы импортировать сигналы, пока мы не будем готовы перейти на более позднюю версию django.from . import handlers
(или подобного)yourapp/signals/__init__.py
?yourproject.
последняя строка блока кода класса TaskConfig. У меня это работает именно с этой структурой, так что рассмотрите этот вопрос :)Я только что столкнулся с этим, и, поскольку мои сигналы не связаны с моделью, я подумал, что добавлю свое решение.
Я регистрирую различные данные о входе / выходе, и мне нужно подключиться к
django.contrib.auth.signals
.Я поместил обработчики сигналов в
signals.py
файл, а затем импортировал сигналы из__init__.py
файла модуля, так как я считаю, что это вызывается, как только приложение запускается (тестирование с помощьюprint
оператора предполагает, что он вызывается еще до того, как файл настроек будет прочитан).# /project/__init__.py import signals
и в signal.py
# /project/signals.py from django.contrib.auth.signals import user_logged_in def on_logged_in(sender, user, request, **kwargs): print 'User logged in as: \'{0}\''.format(user) user_logged_in.connect(on_logged_in)
Я новичок в Django (/ python), поэтому открыт для всех, кто скажет мне, что это ужасная идея!
источник
user_logged_in.connect(on_logged_in)
скорее всего, должен быть передан вdispatch_uid
аргумент. Подробнее см . Docs.djangoproject.com/en/dev/topics/signals/… .Я недавно прочитал эту статью о лучших практиках, когда дело доходит до размещения ваших проектов / приложений, и в ней предлагается, чтобы все ваши настраиваемые сигналы диспетчера помещались в файл с именем
signals.py
. Однако это не решает полностью вашу проблему, поскольку вам все равно нужно куда-то их импортировать, и чем раньше они будут импортированы, тем лучше.Предложение модели хорошее. Поскольку вы уже определили все в своем
signals.py
файле, это не должно занимать больше строки в верхней части файла. Это похоже на то, какadmin.py
файла (с определениями классов вверху и кодом для регистрации всех настраиваемых классов администратора внизу), если вы определяете свои сигналы, затем подключаете их в одном файле.Надеюсь, это поможет! В конечном итоге все сводится к тому, что вы предпочитаете.
источник
signals.py
файл, но не знал, как их потом вызывать. Импортируя его в свойmodels.py
файл, я получил очень чистое решение, не «загрязняющее» мой файл models.py. Спасибо! :)models.py и signal.py в каждом приложении были рекомендованными местами для подключения сигналов, однако, на мой взгляд, они не лучшее решение для отправки сигналов и обработчиков. Диспетчеризация должна быть причиной изобретения сигналов и обработчиков в django.
Я долго боролся, и наконец мы нашли решение.
создать модуль коннектора в папке приложения
так что у нас есть:
app/ __init__.py signals.py models.py connectors.py
в app / connector.py мы определили обработчики сигналов и подключили их. Приведен пример:
from signals import example_signal from models import ExampleModel from django.db.models.signals import post_save, post_delete def hanndler(sender, *args, **kwargs): pass post_save.connect(hander, sender=ExampleModel)
затем в models.py добавляем в конец файла следующую строку:
from app import connector
Здесь все сделано.
Таким образом, мы можем поместить сигналы в signal.py, а все обработчики - в connector.py. Никакого беспорядка в моделях и сигналах.
Надеюсь, это даст другое решение.
источник
Небольшое напоминание о
AppConfig
. Не забудьте установить:# yourapp/__init__.py default_app_config = 'yourapp.apps.RockNRollConfig'
источник
Я храню их в отдельном файле
signals.py
,models.py
после того как все модели определены. Я импортирую их и подключаю модели к сигналам.signal.py
# necessary imports def send_mail_on_save(<args>): # code here
models.py
# imports class mymodel(models.Model): # model here # import signals from signals import send_mail_on_save # connect them post_save.connect(send_mail_on_save,sender=mymodel)
Это обеспечивает мне логическое разделение, конечно, нет ничего плохого в том, чтобы хранить их в models.py , но таким образом легче управлять .
Надеюсь это поможет!!
источник