Ich habe gerade angefangen, Signal-Listener in einem Django-Projekt zu implementieren. Während ich verstehe, was sie sind und wie man sie benutzt. Es fällt mir schwer herauszufinden, wo ich sie hinstellen soll. Die Dokumentation von der Django-Site enthält Folgendes:
Sie können den Signalverarbeitungs- und Registrierungscode an einer beliebigen Stelle eingeben. Sie müssen jedoch sicherstellen, dass das Modul, in dem es sich befindet, frühzeitig importiert wird, damit die Signalverarbeitung registriert wird, bevor Signale gesendet werden müssen. Dies macht die models.py Ihrer App zu einem guten Ort für die Registrierung von Signalhandlern.
Es ist zwar ein guter Vorschlag, aber nicht modellierte Klassen oder Methoden in meinen Modellen zu haben. Py reibt mich einfach in die falsche Richtung.
Was ist dann die beste Vorgehensweise / Regel zum Speichern und Registrieren von Signalhandlern?
quelle
Foo
das Teil von istfooapp
. Der Signalempfänger ist jedoch eine Erweiterung und lebt (zum Beispielotherapp
) in einer anderen App .Dies wurde der Dokumentation hinzugefügt, als Django 1.7 veröffentlicht wurde:
Die beste Vorgehensweise besteht darin, Ihre Handler in handlers.py in einem Signal-Submodul zu definieren, z. B. in einer Datei, die wie folgt aussieht:
yourapp / signales / handlers.py :
Der beste Ort, um Ihren Signalhandler zu registrieren, ist dann in der AppConfig der App, die ihn definiert, mithilfe der ready () -Methode. Das wird so aussehen:
yourapp / apps.py :
Stellen Sie sicher, dass Sie Ihre AppConfig laden, indem Sie sie entweder direkt in INSTALLED_APPS von settings.py oder in
__init__
Ihrer App angeben . Siehe die bereit () Dokumentation für weitere Informationen.Hinweis: Wenn Sie Signale bereitstellen, die auch von anderen Apps abgehört werden sollen, fügen Sie diese in das
__init__
Signalmodul ein, z. B. eine Datei, die wie folgt aussieht:Ihre App / Signale / __ init__.py
Eine andere App kann dann Ihr Signal abhören, indem Sie es importieren und registrieren, z
from yourapp.signals import task_generate_pre_save
. Wenn Sie Ihre Signale von Ihren Handlern trennen, bleiben die Dinge sauber.Anleitung für Django 1.6:
Wenn Sie immer noch mit Django 1.6 oder niedriger arbeiten, tun Sie dasselbe (definieren Sie Ihre Handler in yourapp / signales / handlers.py), aber anstatt AppConfig zu verwenden, laden Sie die Handler über __init__.py von Ihre App, zB so etwas wie:
yourapp / __ init__.py
Dies ist nicht so schön wie die Verwendung der ready () -Methode, da dies häufig zu Problemen beim zirkulären Import führt.
quelle
__init__
Problemumgehung, Importsignale zuzulassen, würde für mich nicht funktionieren. Daher frage ich mich, ob es einen anderen Ort gibt, von dem ich Signale importieren kann, bis wir bereit sind, auf eine spätere Django-Version zu aktualisieren.from . import handlers
(oder ähnliches) gebenyourapp/signals/__init__.py
?yourproject.
in der letzten Zeile des TaskConfig-Klassencodeblocks nicht. Ich habe dies mit genau dieser Struktur arbeiten, also betrachten Sie diese qa :)Ich bin gerade erst darauf gestoßen, und da meine Signale nicht modellbezogen sind, dachte ich, ich würde meine Lösung hinzufügen.
Ich protokolliere verschiedene Daten rund um das Anmelden / Abmelden und musste mich einbinden
django.contrib.auth.signals
.Ich habe die Signalhandler in eine
signals.py
Datei eingefügt und dann Signale aus der__init__.py
Moduldatei importiert , da ich glaube, dass dies aufgerufen wird, sobald die App startet (Tests mit einerprint
Anweisung legen nahe, dass sie aufgerufen wird, noch bevor die Einstellungsdatei gelesen wird.)und in signals.py
Ich bin ziemlich neu in Django (/ python), also bin ich offen für jeden, der mir sagt, dass dies eine schreckliche Idee ist!
quelle
user_logged_in.connect(on_logged_in)
sollte höchstwahrscheinlich in demdispatch_uid
Argument übergeben werden. Mehr unter docs.djangoproject.com/de/dev/topics/signals/… .Ich habe kürzlich diesen Artikel über Best Practices für das Layout Ihrer Projekte / Anwendungen gelesen und er schlägt vor, dass alle Ihre benutzerdefinierten Dispatcher-Signale in einer Datei namens gespeichert werden sollten
signals.py
. Dies löst Ihr Problem jedoch nicht vollständig, da Sie diese noch irgendwo importieren müssen. Je früher sie importiert werden, desto besser.Der Modellvorschlag ist gut. Da Sie bereits alles in Ihrer
signals.py
Datei definiert haben, sollte es nicht mehr als eine Zeile oben in der Datei dauern. Dies ähnelt der Anordnung deradmin.py
Datei (mit Klassendefinitionen oben und dem Code zum Registrieren aller benutzerdefinierten Administratorklassen unten). Wenn Sie Ihre Signale definieren, verbinden Sie sie in derselben Datei.Hoffentlich hilft das! Letztendlich kommt es darauf an, was Sie bevorzugen.
quelle
signals.py
Datei einfügen , wusste aber nicht, wie sie danach aufgerufen werden sollte. Durch den Import in meinemodels.py
Datei erhielt ich eine sehr saubere Lösung, ohne meine Datei models.py zu "verschmutzen". Danke dir! :)Modelle.py und Signale.py in jeder App waren die empfohlenen Orte zum Verbinden von Signalen. Sie sind jedoch meiner Meinung nach nicht die beste Lösung, um Signale und Handler weiterzuleiten. Dispatching sollte der Grund sein, warum Signale und Handler in Django erfunden wurden.
Ich hatte lange Probleme, und schließlich fanden wir die Lösung heraus.
Erstellen Sie ein Connector-Modul im App-Ordner
also haben wir:
In app / connectors.py haben wir Signalhandler definiert und verbunden. Ein Beispiel wird bereitgestellt:
Dann fügen wir in models.py die folgende Zeile am Ende der Datei hinzu:
Alles hier gemacht.
Auf diese Weise können wir Signale in signal.py und alle Handler in connectors.py einfügen. Kein Durcheinander bei Modellen und Signalen.
Hoffe, es bietet eine andere Lösung.
quelle
Ich bewahre sie in einer separaten Datei auf
signals.py
,models.py
nachdem alle Modelle definiert wurden. Ich importiere sie und verbinde Modelle mit Signalen.signale.py
models.py
Dies bietet mir eine logische Trennung, natürlich ist nichts falsch daran, sie in Modellen zu behalten. Py , aber es ist auf diese Weise leichter zu handhaben .
Hoffe das hilft!!
quelle
Kleine Erinnerung an
AppConfig
. Vergessen Sie nicht einzustellen:quelle