Właśnie zacząłem wdrażać odbiorniki sygnału w projekcie django. Chociaż rozumiem, czym one są i jak ich używać. Trudno mi się wymyślić, gdzie je umieścić. Dokumentacja ze strony django ma do powiedzenia:
Gdzie powinien znajdować się ten kod?
Możesz umieścić obsługę sygnału i kod rejestracyjny w dowolnym miejscu. Musisz jednak upewnić się, że moduł, w którym się znajduje, zostanie zaimportowany wcześnie, aby obsługa sygnału została zarejestrowana, zanim jakiekolwiek sygnały będą musiały zostać wysłane. To sprawia, że models.py twojej aplikacji jest dobrym miejscem do umieszczenia rejestracji programów obsługi sygnału.
Chociaż jest to dobra sugestia, posiadanie w moich models.py klas lub metod innych niż modelowe po prostu źle mnie przeciera.
Jaka jest zatem najlepsza praktyka / zasada dotycząca przechowywania i rejestrowania programów obsługi sygnału?
źródło
Foo
którego jest częściąfooapp
. Ale odbiornik sygnału jest rozszerzeniem i działa w innej aplikacji (na przykładotherapp
).Zostało to dodane do dokumentacji po wydaniu Django 1.7 :
Najlepszą praktyką jest zdefiniowanie swoich handlerów w handlers.py w module podrzędnym sygnałów, np. W pliku, który wygląda tak:
twojaaplikacja / sygnały / handlers.py :
Najlepszym miejscem do zarejestrowania modułu obsługi sygnału jest następnie w AppConfig aplikacji, która go definiuje, przy użyciu metody ready () . Będzie to wyglądać tak:
yourapp / apps.py :
Upewnij się, że ładujesz swoją AppConfig, określając ją bezpośrednio w
__init__
aplikacji INSTALLED_APPS settings.py lub w aplikacji. Zobacz dokumentację ready (), aby uzyskać więcej informacji.Uwaga: jeśli zapewniasz sygnały, które mają nasłuchiwać również inne aplikacje, umieść je
__init__
w swoim module sygnałów, np. Plik, który wygląda tak:twojaaplikacja / sygnały / __ init__.py
Inna aplikacja może wtedy słuchać Twojego sygnału, importując go i rejestrując, np
from yourapp.signals import task_generate_pre_save
. Oddzielenie sygnałów od obsługi pozwala zachować porządek.Instrukcje dla Django 1.6:
Jeśli nadal utkniesz w Django 1.6 lub niższym, zrobiłbyś to samo (zdefiniowałbyś swoje programy obsługi w yourapp / signal / handlers.py), ale zamiast używać AppConfig, załadowałbyś moduły obsługi przez __init__.py Twoja aplikacja, np. coś takiego:
yourapp / __ init__.py
Nie jest to tak przyjemne jak użycie metody ready (), ponieważ często powoduje problemy z importowaniem cyklicznym.
źródło
__init__
importowanie sygnałów nie zadziała dla mnie, więc zastanawiam się, czy jest inne miejsce, z którego mógłbym importować sygnały, dopóki nie będziemy gotowi do aktualizacji do późniejszej wersji django.from . import handlers
(lub podobnego) wyourapp/signals/__init__.py
?yourproject.
w ostatnim wierszu bloku kodu klasy TaskConfig. Mam to działające z dokładnie taką strukturą, więc rozważ to qa :)Dopiero co się z tym spotkałem, a ponieważ moje sygnały nie są związane z modelem, pomyślałem, że dodam swoje rozwiązanie.
Loguję różne dane dotyczące logowania / wylogowania i muszę się podłączyć
django.contrib.auth.signals
.Umieściłem programy obsługi sygnałów w
signals.py
pliku, a następnie zaimportowałem sygnały z__init__.py
pliku modułu, ponieważ uważam, że jest to wywoływane zaraz po uruchomieniu aplikacji (testowanie zprint
instrukcją sugeruje, że jest wywoływane nawet przed odczytaniem pliku ustawień).i w signal.py
Jestem całkiem nowy w Django (/ python), więc jestem otwarty na każdego, kto powie mi, że to okropny pomysł!
źródło
user_logged_in.connect(on_logged_in)
powinien najprawdopodobniej przekazaćdispatch_uid
argument. Więcej na docs.djangoproject.com/en/dev/topics/signals/… .Niedawno przeczytałem ten artykuł o najlepszych praktykach, jeśli chodzi o układanie projektów / aplikacji, i sugeruje, że wszystkie niestandardowe sygnały dyspozytora powinny znajdować się w pliku o nazwie
signals.py
. Jednak nie rozwiązuje to w pełni problemu, ponieważ nadal musisz je gdzieś zaimportować, a im wcześniej zostaną zaimportowane, tym lepiej.Propozycja modelu jest dobra. Ponieważ zdefiniowałeś już wszystko w swoim
signals.py
pliku, nie powinno to zająć więcej niż linię na początku pliku. Jest to podobne do sposobuadmin.py
ułożenia pliku (z definicjami klas na górze i kodem do rejestracji wszystkich niestandardowych klas administracyjnych na dole), jeśli zdefiniujesz sygnały, połącz je w tym samym pliku.Mam nadzieję, że to pomoże! Ostatecznie wszystko sprowadza się do tego, co wolisz.
źródło
signals.py
pliku, ale nie wiedziałem, jak to się później nazywa. Importując go do mojegomodels.py
pliku, otrzymałem bardzo czyste rozwiązanie, bez „zanieczyszczania” mojego pliku models.py. Dziękuję Ci! :)Models.py i signal.py w każdej aplikacji były zalecanymi miejscami do łączenia sygnałów, jednak moim zdaniem nie są one najlepszym rozwiązaniem do wysyłania sygnałów i obsługi. Wysyłanie powinno być przyczyną sygnałów i procedur obsługi wymyślonych w django.
Walczyłem przez długi czas i w końcu znaleźliśmy rozwiązanie.
utwórz moduł łącznika w folderze aplikacji
więc mamy:
w app / connector.py zdefiniowaliśmy programy obsługi sygnału i połączyliśmy je. Podano przykład:
następnie w models.py dodajemy następujący wiersz na końcu pliku:
Wszystko zrobione tutaj.
W ten sposób możemy umieścić sygnały w plikach signal.py, a wszystkie programy obsługi w złączach.py. Bez bałaganu w modelach i sygnałach.
Mam nadzieję, że zapewnia inne rozwiązanie.
źródło
Trzymam je w osobnym pliku
signals.py
Inmodels.py
po zdefiniowaniu wszystkich modeli. Importuję je i podłączam modele do sygnałów.sygnały.py
models.py
To zapewnia mi logiczną separację, oczywiście nie ma nic złego w trzymaniu ich w models.py , ale w ten sposób jest łatwiejsze do zarządzania.
Mam nadzieję że to pomoże!!
źródło
Małe przypomnienie o
AppConfig
. Nie zapomnij ustawić:źródło