これは、Django 1.7のリリース時にドキュメントに追加されました。
厳密に言えば、信号処理と登録コードは好きな場所に配置できますが、アプリケーションのルートモジュールとそのモデルモジュールを避けて、コードのインポートによる副作用を最小限に抑えることをお勧めします。
実際には、シグナルハンドラは通常、関連するアプリケーションのシグナルサブモジュールで定義されます。シグナルレシーバーは、アプリケーション構成クラスのready()メソッドで接続されます。receiver()デコレーターを使用している場合は、ready()内に信号サブモジュールをインポートするだけです。
Django 1.7で変更:以前のバージョンのDjangoにはready()が存在しなかったため、通常、信号の登録はモデルモジュールで行われていました。
ベストプラクティスは、次のようなファイルなど、シグナルサブモジュールのhandlers.pyでハンドラーを定義することです。
yourapp / signals / 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
シグナルハンドラーを登録するのに最適な場所は、ready()メソッドを使用して、シグナルハンドラーを定義するアプリのAppConfig内です。これは次のようになります。
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
settings.pyのINSTALLED_APPSで直接、または__init__
アプリので指定して、AppConfigをロードしていることを確認してください。詳細については、ready()のドキュメントを参照してください。
注:他のアプリも同様にリッスンするシグナルを提供する場合は、それらを__init__
シグナルモジュールに入れます(例:次のようなファイル)。
yourapp / signals / __ 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 / signals / handlers.pyでハンドラーを定義します)。ただし、AppConfigを使用する代わりに、__ init__.pyを介してハンドラーをロードします。あなたのアプリ、例えば次のようなもの:
yourapp / __ init__.py
import signals
これは、ready()メソッドの使用ほどよくありません。循環インポートの問題を引き起こすことが多いからです。