tutorial sitio proyecto page mvt estructura español ejemplo aplicacion django signal-handling

sitio - tutorial django 2 español



¿Dónde deberían los controladores de señales vivir en un proyecto django? (6)

De hecho, me gusta hacerlos classmethods del modelo en sí. Eso mantiene todo dentro de una clase, y significa que no tiene que preocuparse de importar nada.

Acabo de comenzar a implementar oyentes de señal en un proyecto django. Mientras entiendo lo que son y cómo usarlos. Me está costando trabajo averiguar dónde debo ponerlos. La documentación del sitio django tiene esto que decir:

¿Dónde debería vivir este código?

Puede poner el código de manejo y registro de señal en cualquier lugar que desee. Sin embargo, deberá asegurarse de que el módulo en el que se encuentra se importe desde el principio para que el manejo de la señal se registre antes de enviar señales. Esto hace que models.py de su aplicación sea un buen lugar para colocar el registro de manejadores de señal.

Si bien es una buena sugerencia, tener clases o métodos no modelo en mi models.py simplemente me da un mal sentido.

Entonces, ¿cuál es la mejor práctica / regla para almacenar y registrar manejadores de señal?


Esto se agregó a la documentation cuando se lanzó Django 1.7 :

Estrictamente hablando, el código de manejo y registro de señales puede vivir en cualquier lugar que desee, aunque se recomienda evitar el módulo raíz de la aplicación y su módulo de modelos para minimizar los efectos secundarios de la importación de código.

En la práctica, los manejadores de señales generalmente se definen en un submódulo de señales de la aplicación a la que se refieren. Los receptores de señal están conectados en el método ready () de la clase de configuración de la aplicación. Si está utilizando el decorador de receptor (), simplemente importe el submódulo de señales dentro de listo ().

Modificado en Django 1.7: Como ready () no existía en las versiones anteriores de Django, el registro de la señal generalmente ocurría en el módulo de modelos.

La mejor práctica es definir sus manejadores en handlers.py en un submódulo de señales, por ejemplo, un archivo que se ve así:

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

El mejor lugar para registrar su manejador de señal es entonces en AppConfig de la aplicación que lo define, utilizando el método ready () . Esto se verá así:

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

Asegúrese de cargar su AppConfig especificándola directamente en INSTALLED_APPS de settings.py o en el __init__ de su aplicación. Consulte la documentación de ready () para obtener más información.

Nota: Si está proporcionando señales para que otras aplicaciones también las escuchen, colóquelas en __init__ en su módulo de señales, por ejemplo, un archivo que se vea como __init__ :

yourapp / signals / __ init__.py

import django.dispatch task_generate_pre_save = django.dispatch.Signal(providing_args=["task"])

Otra aplicación puede escuchar tu señal importándola y registrándola, por ejemplo, from yourapp.signals import task_generate_pre_save . Separar las señales de sus manejadores mantiene las cosas limpias.

Instrucciones para Django 1.6:

Si todavía estás atascado en Django 1.6 o menos, entonces harías lo mismo (define tus controladores en yourapp / signals / handlers.py) pero en lugar de usar AppConfig, cargarías los manejadores a través del __init__.py de su aplicación, por ejemplo, algo así como:

yourapp / __ init__.py

import signals

Esto no es tan bueno como usar el método ready () porque a menudo causa problemas circulares de importación.


Los guardo en un archivo separado signals.py , en models.py después de definir todos los modelos. Los importo y conecto modelos a señales.

signals.py

# necessary imports def send_mail_on_save(<args>): # code here

models.py

# imports class mymodel(models.Model): # model here # import signals from signals import send_mail_on_save # connect them post_save.connect(send_mail_on_save,sender=mymodel)

Esto me proporciona una separación lógica, por supuesto que no hay nada de malo en mantenerlos en models.py , pero es más manejable de esta manera.

¡¡Espero que esto ayude!!


Me acabo de enterar de esto, y como mis señales no están relacionadas con el modelo, pensé que agregaría mi solución.

Estoy registrando varios datos alrededor de iniciar / cerrar sesión, y necesitaba engancharme en django.contrib.auth.signals .

He puesto los manejadores de señal en un archivo signals.py , y luego __init__.py señales desde el archivo __init__.py módulo, ya que creo que esto se llama tan pronto como se inicia la aplicación (las pruebas con una declaración print sugieren que se llama incluso antes el archivo de configuración es leído.)

# /project/__init__.py import signals

y en 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)

Soy bastante nuevo para Django (/ python) así que estoy abierto a cualquiera que me diga que esta es una idea terrible.


Recientemente leí this artículo sobre las mejores prácticas a la hora de diseñar sus proyectos / aplicaciones, y sugiere que todas las señales de su despachador personalizado deben ir en un archivo llamado signals.py . Sin embargo, eso no resuelve completamente su problema, ya que aún necesita importarlos en algún lugar, y cuanto antes se importen, mejor.

La sugerencia del modelo es buena. Como ya signals.py todo en tu archivo signals.py , no debería tomar más de una línea en la parte superior del archivo. Esto es similar a la forma en que se presenta el archivo admin.py (con las definiciones de clase en la parte superior y el código para registrar todas las clases de administración personalizadas en la parte inferior), si define sus señales y luego las conecta en el mismo archivo.

¡Espero que ayude! En definitiva, se reduce a lo que prefieres.


models.py y signals.py en cada aplicación han sido los lugares recomendados para conectar las señales, sin embargo, no son la mejor solución, en mi opinión, para mantener enviadas señales y controladores. El envío debería ser la razón por la que las señales y los controladores se inventaron en django.

Estuve luchando durante mucho tiempo, y finalmente descubrimos la solución.

crear un módulo de conector en la carpeta de la aplicación

entonces tenemos:

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

en app / connectors.py, definimos manejadores de señal y los conectamos. Se proporciona un ejemplo:

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)

luego en models.py, agregamos la siguiente línea al final del archivo:

from app import connector

Todo hecho aquí.

De esta manera, podemos poner señales en signals.py, y todos los controladores en connectors.py. Sin desorden en modelos y señales.

Espero que brinde otra solución.