Basierend auf der Dokumentation von Django, die ich gelesen habe, scheint es, als wäre signals.py
der App-Ordner ein guter Anfang, aber das Problem, mit dem ich konfrontiert bin, ist, dass wenn ich Signale für erstelle pre_save
und versuche, die Klasse aus dem Modell zu importieren, dies mit dem in Konflikt steht import
in meinem Modell.
# models.py
from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import gettext as _
from signals import *
class Comm_Queue(CommunicatorAbstract):
queue_statuses = (
('P', _('Pending')),
('S', _('Sent')),
('E', _('Error')),
('R', _('Rejected')),
)
status = models.CharField(max_length=10, db_index=True, default='P')
is_html = models.BooleanField(default=False)
language = models.CharField(max_length=6, choices=settings.LANGUAGES)
sender_email = models.EmailField()
recipient_email = models.EmailField()
subject = models.CharField(max_length=100)
content = models.TextField()
# signals.py
from django.conf import settings
from django.db.models.signals import pre_save
from django.dispatch import receiver
from models import Comm_Queue
@receiver(pre_save, sender=Comm_Queue)
def get_sender_email_from_settings(sender, **kwargs):
obj=kwargs['instance']
if not obj.sender_email:
obj.sender_email='%s' % settings.ADMINS[0][1]
Dieser Code wird nicht ausgeführt, da ich Comm_Queue
innen importiere signals.py
und auch die Signale darin importiere models.py
.
Kann mir jemand einen Rat geben, wie ich dieses Problem lösen kann?
Grüße
django
django-signals
Mo J. Mughrabi
quelle
quelle
Antworten:
Ursprüngliche Antwort für Django <1,7:
Sie können die Signale registrieren, indem Sie sie
signals.py
in die App-__init__.py
Datei importieren :Dies ermöglicht den Import
models.py
vonsignals.py
ohne Kreisimportfehler.Ein Problem bei diesem Ansatz besteht darin, dass die Abdeckungsergebnisse durcheinander gebracht werden, wenn Sie Coverage.py verwenden.
Verwandte Diskussion
Edit: Für Django> = 1.7:
Seit der Einführung von AppConfig liegt die empfohlene Methode zum Importieren von Signalen in ihrer
init()
Funktion. Siehe Eric Marcos' Antwort für weitere Details.quelle
AppRegistryNotReady("Apps aren't loaded yet.")
Wenn Sie Django <= 1.6 verwenden, würde ich die Kamagatos-Lösung empfehlen: Importieren Sie einfach Ihre Signale am Ende Ihres Modellmoduls.
Für zukünftige Versionen von Django (> = 1.7) wird empfohlen , Ihr Signalmodul in die config ready () -Funktion Ihrer App zu importieren :
my_app/apps.py
my_app/__init__.py
quelle
doesn't declare an explicit app_label
Um Ihr Problem zu lösen, müssen Sie nach Ihrer Modelldefinition nur signal.py importieren. Das ist alles.
quelle
Ich habe auch Signale in die Datei signals.py eingefügt und habe auch dieses Code-Snippet, das alle Signale lädt:
Dies ist für ein Projekt, ich bin mir nicht sicher, ob es auf App-Ebene funktioniert.
quelle
In alten Django-Versionen wäre es in Ordnung, die Signale auf das
__init__.py
oder vielleicht auf das zu setzenmodels.py
(obwohl die Modelle am Ende für meinen Geschmack viel zu groß sein werden).Mit Django 1.9 ist es meiner Meinung nach besser, die Signale in eine
signals.py
Datei zu platzieren und sie mit dem zu importierenapps.py
, wo sie nach dem Laden des Modells geladen werden.apps.py:
Sie können Ihre Signale auch in
signals.py
undhandlers.py
in einem anderen Ordner innerhalb Ihres Modells mit dem Namen aufteilensignals
, aber für mich ist das etwas über das Engineering hinaus. Schauen Sie sich das Platzieren von Signalen anquelle
Ich vermute, dass Sie das tun, damit Ihre Signale registriert werden und irgendwo gefunden werden. Ich habe meine Signale normalerweise direkt in eine models.py-Datei eingefügt.
quelle
Dies gilt nur, wenn Sie Ihre Signale in einer separaten
signals.py
Datei habenIn völliger Übereinstimmung mit der Antwort von @EricMarcos, aber es sollte angegeben werden, dass die Django- Dokumente ausdrücklich raten, die Variable default_app_config nicht zu verwenden (obwohl es nicht falsch ist). Für aktuelle Versionen wäre der richtige Weg:
my_app / apps.py
settings.py
(Stellen Sie sicher, dass Sie nicht nur Ihren App-Namen in installierten Apps haben, sondern stattdessen den relativen Pfad zu Ihrer AppConfig.)
quelle
Eine Alternative besteht darin, die Rückruffunktionen zu importieren
signals.py
und zu verbinden inmodels.py
:Signale.py
model.py
Ps: Beim Importieren
YourModel
insignals.py
wird eine Rekursion erstellt. Verwenden Siesender
stattdessen.Ps2: Wenn Sie die Instanz erneut in der Rückruffunktion speichern, wird eine Rekursion erstellt. Sie können ein Steuerargument in der
.save
Methode erstellen, um es zu steuern.quelle