One of the benefits of the app structure of Django is that disparate pieces of your project don’t necessarily know about each other. But sometimes something happening in one app needs to trigger an action in another. Signals to the rescue.

Built in Signals

Some signals, such as , come built in. They are called every time an instance of their sender is saved. For example:

That’s a receiver that is called every time a signal is passed. To break it down a little:

  • This is in a file called , within the app that holds the pieces relevant to what the function will change. Not usually the same app as the sender model
  • It uses the decorator, to declare that the function that follows is the receiver of a signal.
  • The and arguments to the decorator that it will be called every time an instance of Model is saved.

The function takes:

  • An instance (the instance of the Model that was saved)
  • Whether the instance was just created or not — you may want different behavior depending on whether it was created or updated
  • , which is an optional list of the fields that were changed on the instance, in case you want the behavior to differ based on what changed. You’d have to call it like so:

If you don’t want to pass update_fields, you can just call .save() on your object like you would any other time, and the signal will be sent.

Custom Signals

Sometimes the built in signals just don’t meet your needs. Here’s how to define a custom one (within the file of the app where the receiver will be defined):

You then need to call it manually whenever you want the signal sent:

In this case, the user and attributes map pretty well to the instance and attributes used in the built-in post_save signal, but these can be called whatever you want, and you can send anything you want along with the signal though. However, the method does only take two arguments, so these need to be named as part of .

Your receiver would then look like this:

Other Configuration

If these are your project’s first signals (or if you’re adding them to an app within your project for the first time), you’ll need to make sure your signals are loaded before any code runs. Within the file of your app, make sure to import the signals inside your ready function:

Questions? Thoughts on ways to do this better or other implementations? I’ve noticed a lack of people writing about using Django, but I’m still new to the framework, and am always open to suggestions!

Senior Software Engineer | www.adriennedomingus.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store