160 votes

Où les gestionnaires de signaux doivent-ils vivre dans un projet django?

Je viens de commencer la mise en œuvre de signal auditeurs dans un projet django. Bien que je comprenne ce qu'ils sont et comment les utiliser. Je vais avoir un moment difficile essayer de comprendre où je dois les mettre. La documentation du site django a ceci à dire:

Où mettre ce code en direct?

Vous pouvez mettre de traitement du signal et code d'enregistrement de n'importe où vous le souhaitez. Cependant, vous devez vous assurer que le module c'est dans importés début sur de sorte que le traitement du signal obtient enregistrer les signaux doivent être envoyé. Cela permet à votre application modèles.py un bon endroit pour mettre l'enregistrement des gestionnaires de signaux.

Alors que ses une bonne idée, non du modèle de classes ou de méthodes dans mon models.py juste me frotte le mauvais sens.

Alors, quelle est la meilleure pratique/règle pour le stockage et l'enregistrement des gestionnaires de signaux?

269voto

Aidan Points 630

Comme de Django 1.7:

Strictement parlant, traitement du signal et le code d'enregistrement peuvent vivre n'importe où vous le souhaitez, mais il est recommandé d'éviter l'application de la racine du module et de ses modèles de module afin de minimiser les effets secondaires de l'importation de code.

Dans la pratique, les gestionnaires de signaux sont généralement définies dans un des signaux de sous-module de l'application à laquelle elles se rapportent. Les récepteurs de signaux sont connectés dans le prêt() la méthode de configuration de votre application de classe. Si vous utilisez le récepteur() décorateur, il suffit d'importer les signaux de sous-module à l'intérieur de ready().

Changé dans Django 1.7: Depuis prêt() n'existe pas dans les versions précédentes de Django, le signal d'enregistrement généralement le cas dans les modèles de module.

Cela fait partie de Django 1.7 nouveau AppConfig tout ça, c'est la documentation de prêt(): https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready

Si vous n'êtes pas à l'aide de 1,7 encore, alors la meilleure pratique (avec un oeil pour ne pas avoir à changer beaucoup lorsque vous mettez à niveau à 1,7) serait quelque chose comme ceci:

Dans un nouveau fichier yourapp/signals.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):

Puis dans yourapp/__ init__.py

import signals

Lorsque vous mettez à niveau à Django 1.7, vous souhaitez supprimer le "importation .des signaux" de votre __ init__.py et ajouter un yourapp/apps.py comme suit:

from django.apps import AppConfig

class ReportsConfig(AppConfig):
    name = 'reports'
    verbose_name = "Reports"

    def ready(self):
        import signals

40voto

Hugo Rodger-Brown Points 2360

Je viens juste de tomber sur ce, et comme mon signaux ne sont pas axés sur le modèle je pensais que je voudrais ajouter ma solution.

Je suis la journalisation des différentes données de connexion / déconnexion, et nécessaires à crochet en django.contrib.auth.signals.

J'ai mis les gestionnaires de signaux en signals.py le fichier, puis importé des signaux à partir de l' __init__.py le fichier du module, comme je le crois, ce qui est appelé dès que l'application démarre (test avec un print déclaration suggère qu'elle est appelée avant même que le fichier de paramètres est à lire.)

# /project/__init__.py
import signals

et dans signals.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)

Je suis assez nouveau à Django (/python) donc je suis ouverte à toute personne me disant que c'est une idée terrible!

40voto

Daniel Roseman Points 199743

J'aime en fait leur faire des méthodes de classe du modèle lui-même. Cela garde tout dans une classe et vous évite d'importer quoi que ce soit.

13voto

hora Points 1151

Je viens de lire cet article sur les meilleures pratiques lorsqu'il s'agit de présenter vos projets/demandes, et il suggère que tous vos personnalisée répartiteur de signaux devraient aller dans un fichier appelé" signals.py. Cependant, cela n'est pas complètement résolu votre problème, puisque vous avez encore besoin pour l'importation de ces quelque part, et le plus tôt ils obtenir importé le mieux.

Le modèle suggestion est bonne. Puisque vous avez déjà défini tout dans votre signals.py le fichier, il ne devrait pas prendre plus d'une ligne en haut du fichier. Ceci est similaire à la façon dont l' admin.py le fichier est mis en place avec les définitions de classe dans le haut et le code pour l'enregistrement de toutes les admin classes d'en bas), si vous définissez vos signaux puis les relier entre eux dans le même fichier.

Espérons que ça aide! Il revient en définitive à ce que vous préférez.

9voto

samuel Points 121

models.py et signals.py dans chaque application ont été les endroits recommandés pour connecter des signaux, cependant, ils ne sont pas la meilleure solution, à mon avis, de garder des signaux et des gestionnaires d'expédition. Envoi doit être la raison pour laquelle les signaux et les gestionnaires inventé dans django.

J'ai eu du mal pendant un long moment, et finalement nous avons trouvé la solution.

créer un connecteur de module dans le dossier app

nous avons donc:

app/
    __init__.py
    signals.py
    models.py
    connectors.py

dans app/connectors.py nous avons défini les gestionnaires de signaux et de les connecter. Un exemple est fourni:

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)

puis dans models.py, nous ajoutons la ligne suivante à la fin du fichier:

from app import connector

Tout ce qui est fait ici.

De cette façon, nous pouvons mettre des signaux dans signals.py et tous les maîtres-chiens dans connectors.py. Pas de gâchis dans les modèles et les signaux.

Espérons qu'il fournit une autre solution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X