mostrar - el lugar correcto para mantener mis archivos signal.py en django
manejo de imagenes django (7)
Respuesta original, para Django <1.7:
Puede registrar las señales importando a signals.py
en el archivo __init__.py
la aplicación:
# __init__.py
import signals
Esto permitirá importar models.py
desde signals.py
sin errores de importación circulares.
Un problema con este enfoque es que desordena los resultados de la cobertura si está utilizando cobertura.py.
Edición: Para Django> = 1.7:
Desde que se introdujo AppConfig, la forma recomendada de importar señales es en su función init()
. Vea la respuesta de Eric Marcos para más detalles.
Según la documentación que estaba leyendo en el sitio de django, parece que signs.py en la carpeta de aplicaciones es un buen lugar para comenzar, pero el problema al que me enfrento es que cuando creo señales para pre_save e intento importar la clase modelo, entra en conflicto con la operación de importación para la tarea en el modelo. ver mi código a continuación
model.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()
señales.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]
este código no se ejecutará porque estoy importando Comm_queue dentro de las señales y estoy haciendo * importar a las señales dentro de los modelos.py. ¿Puede algún consejo cómo puedo superar este problema?
Saludos,
En versiones anteriores de Django estaría bien colocar las señales en __init__.py
o tal vez en models.py
(aunque al final los modelos serán __init__.py
grandes para mi gusto).
Con Django 1.9, creo que es mejor colocar las señales en un archivo signals.py
e importarlas con apps.py
, donde se apps.py
después de cargar el modelo.
apps.py:
from django.apps import AppConfig
class PollsConfig(AppConfig):
name = ''polls''
def ready(self):
from . import signals # NOQA
También puede dividir sus señales en signals.py
y handlers.py
en otra carpeta dentro de su modelo con el nombre de las signals
también, pero para mí eso es solo ingeniería. Eche un vistazo a las señales de colocación
Para resolver su problema, solo tiene que importar signal.py después de la definición de su modelo. Eso es todo.
Si está usando Django <= 1.6, recomendaría la solución Kamagatos: solo importe sus señales al final del módulo de sus modelos.
Para futuras versiones de Django (> = 1.7), la forma recommended es importar su módulo de señales en la función de configuración ready() su aplicación:
my_app/apps.py
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = ''my_app''
def ready(self):
import my_app.signals
my_app/__init__.py
default_app_config = ''my_app.apps.MyAppConfig''
Supongo que estás haciendo eso para que tus señales se registren, para que se encuentren en algún lugar. Simplemente coloco mis señales en un archivo models.py normalmente.
También puse señales en el archivo signal.py y también tengo este fragmento de código que carga todas las señales:
# import this in url.py file !
import logging
from importlib import import_module
from django.conf import settings
logger = logging.getLogger(__name__)
signal_modules = {}
for app in settings.INSTALLED_APPS:
signals_module = ''%s.signals'' % app
try:
logger.debug(''loading "%s" ..'' % signals_module)
signal_modules[app] = import_module(signals_module)
except ImportError as e:
logger.warning(
''failed to import "%s", reason: %s'' % (signals_module, str(e)))
Esto es para proyecto, no estoy seguro de si funciona a nivel de aplicación.
Una alternativa es importar las funciones de devolución de llamada de signals.py
y conectarlas en models.py
:
señales.py
def pre_save_callback_function(sender, instance, **kwargs):
# Do stuff here
model.py
# Your imports here
from django.db.models.signals import pre_save
from yourapp.signals import pre_save_callback_function
class YourModel:
# Model stuff here
pre_save.connect(pre_save_callback_function, sender=YourModel)
Ps: Importar YourModel
en signals.py
creará una recursión; usa sender
, en su lugar
Ps2: Guardar la instancia de nuevo en la función de devolución de llamada creará una recursión. Puedes hacer un argumento de control en el método .save
para controlarlo.