Based on Django's documentation I was reading, it seems like signals.py
in the app folder is a good place to start with, but the problem I'm facing is that when I create signals for pre_save
and I try to import the class from model it conflicts with the import
in my model.
# 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]
This code will not run because I import Comm_Queue
inside signals.py
and I also import the signals inside models.py
.
Can anyone advice on how I could over come this issue?
Regards
There are 3 types of signal. pre_save/post_save: This signal works before/after the method save(). pre_delete/post_delete: This signal works before after delete a model's instance (method delete()) this signal is thrown.
Only use signals to avoid introducing circular dependencies. If you have two apps, and one app wants to trigger behaviour in an app it already knows about, don't use signals. The app should just import the function it needs and call it directly.
pre_save) is provoked just before the model save() method is called, or you could say model save method is called only after pre_save is called and done its job free of errors.
Django Signals - post_delete()To notify another part of the application after the delete event of an object happens, you can use the post_delete signal.
If you're using Django<=1.6 I'd recommend Kamagatos solution: just import your signals at the end of your models module.
For future versions of Django (>=1.7), the recommended way is to import your signals module in your app's config ready() function:
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'
You can register the signals by importing signals.py
in the app's __init__.py
file:
# __init__.py import signals
This will allow to import models.py
from signals.py
without circular import errors.
One problem with this approach is that it messes up the coverage results if you're using coverage.py.
Related discussion
Since AppConfig was introduced, the recommended way of importing signals is in its init()
function. See Eric Marcos' answer for more details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With