part — 11

We have been adding profiles through admin page but we don’t want such on the production, instead we want the profile to be created automatically with the default image for every user(whenever a user is created). We can do this with signals in Django.

The signals are utilities that allow us to associate events(creating profile) with actions(user is created). We can develop a function that will run when a signal(notify) calls it.

Let me give you a basic example:

models.py

from django.db import models
from django.db.models import signals
def create_cookie(sender, instance, created, **kwargs):
print "Let's start making cookies now"
class Cookie(models.Model):
quantity= models.IntegerField()
additions= models.TextField()
signals.post_save.connect(receiver=create_cookie, sender=Cookie)

This can be written using receiver decorator present in

from django.db import models
from django.db.models import signals
from django.dispatch import receiver

class Cookie(models.Model):
quantity= models.IntegerField()
additions= models.TextField()
@receiver(signals.post_save, sender=Cookie) #sender will be class
def create_cookie(sender, instance, created, **kwargs):
print "Let's start making cookies now"

Shell

>>> obj = Cookie(quantity=3, addition='Add Extra choco chips')>>> obj.save()
Cooking is called

A signal(post_save) is emitted whenever a Cookie(sender) instance is saved/created to create_cookie.

The connection between the senders and the receivers is done through “signal dispatchers”, which are instances of Signal, via the connect method.

And now let’s use it in our project to make profiles for user and for that let’s put our code in a new file under users as signals.py(as recommended by django doc)

from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
# A post_save signal received when a User instance is created
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()

The create_profile function creates profile for the user’s instance if a user instance was created.Now that we have profile for user we need to save it whenever a user or profile model instance is created or updated using save_profile function

The arguments in the create_profile and save_profile are those of post_save . If you suppress the sender argument, the save_profile and create_profile function will be executed after any Django model executes the save method.

Now in users/apps.py

from django.apps import AppConfigclass UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals #noqa

we are importing the signals in ready function to avoid circular dependencies (as django docs recommend to do it this way).

And in users/__init__.py

default_app_config = ‘users.apps.UsersConfig'

You can avoid this line if you’ve added this in your installed apps instead of ‘users’

Run your server and test by creating new users..

Next Up..

Posting Django Tutorials with Beginner to Advanced Projects

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