SoFunction
Updated on 2024-10-30

Teaching you how to properly use Signal in Django 1.6

The short answer is: Signal is the last resort when nothing else will do.

Because new django developers who learn about signal are often happy to use it. They use signal wherever they can, and it's a way for them to feel like django experts. However, after coding like this for a while, django projects can become very complex, with many things getting tangled up.

Many developers also confuse django signals with asynchronous message queues (such as celery). Signals are synchronous, so there is no performance gain when calling a processing-heavy process through a signal. In fact, it is considered a bad habit to move these processing-intensive processes to signal.

1. When to use signal

Do not use signal in the following cases.

signal is closely related to a model, and can be moved to the save() of that model.
When signal can be replaced with model manager
When signal is closely related to a view, and can be moved to that view, it can be used as a signal.
Signal can be used in the following cases.

When signal receivers need to modify multiple models at the same time
When directing the same signal from multiple apps to the same receiver for processing
When the cache is cleared after a mod is saved.
When no other method is available, but a called function is needed to deal with some problem.
2. Substitution of Signal

Using mod and manager

The following code demonstrates the need to notify the administrator when a user creates an Event model. If you rewrite post_save() in the model, you need to add additional logic to distinguish between the user and the administrator.

# myapp/
 from  import models

 class EventManager():

 def create_event(self, title, start, end, creator):
 event = (title=title, start=start, end=end, creator=creator)
 ()
 event.notify_admins()
 return event

Set the model manager in the model.

# myapp/
 from  import settings
 from  import mail_admins
 from  import models

 from model_utils.models import TimeStampedModel
 from .managers import EventManager

 class Event(TimeStampedModel):

 STATUS_UNREVIEWED, STATUS_REVIEWED = (0, 1)
 STATUS_CHOICES = (
 (STATUS_UNREVIEWED, "Unreviewed"),
 (STATUS_REVIEWED, "Reviewed")
 )

 title = (max_length=100)
 start = ()
 end = ()
 status = (choices=STATUS_CHOICES, default=STATUS_UNREVIEWED)
 creator = (settings.AUTH_USER_MODEL)
 objects = EventManager()

 def notify_admins(self):
 subject = "{user} submitted a new event!".format(user=.get_full_name())
 message = """TITLE: {title}
 START: {start}
 END: {end}""".format(title=, start=, end=)
 mail_admins(subject=subject, message=message, fail_silently=False)

If you use create_event() instead of create() in the view, it will notify the administrator.

Validating mods in other code

If you are using the pre_save signal to validate a model, try writing your own validator instead. If the validation is via a ModelForm, implement the validation by rewriting clean().

Using the model's save() and delete()

If you use the pre_save or post_save signal, move that code to the model's save() method if you can.

Also if you use the pre_delete or post_delete signal, move the code to the model's delte() method if you can.

Use other code instead of signal

If possible, we can implement the signal logic using other helper programs.