Search code examples
djangodjango-signals

Use signal function to create Profile object upon creation of User object


I am a following a tutorial on Django and have the following models.py

from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(default = 'default.jpg', upload_to = 'profile_pics')

    def __str__(self):
        return f"{self.user.username} Profile"

I use the register view to create a User object:

def register(request):
    if request.method == 'POST': # if form was submitted w data
        form = UserRegisterForm(request.POST) #instantiate form w post data
        if form.is_valid():
            form.save() #save user to db
            username = form.cleaned_data.get('username') #get this to print out success message
            messages.success(request, f"Your account has been created. You are now able to log in.") #Formatted string literal for f-string
            return redirect('login')
    else:
        form = UserRegisterForm()
    return render(request, 'users/register.html', {'form':form})

Upon creation of a User object I am trying to use signals to create a Profile object. I have created a signals.py file in my app directory:

from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile

#Run this function every time a User is created
@receiver(post_save, sender = User)
def create_profile(sender, instance, created, **kwargs):
    if created: #if User was created
        Profile.objects.create(user = instance)

 @receiver(post_save, sender = User)
 def save_profile(sender, instance, **kwargs):
     instance.profile.save()

and have imported the signals within the ready method of apps.py:

from django.apps import AppConfig


class UsersConfig(AppConfig):
    name = 'users'

    # To make signals work you have to import your signals
    # inside the ready method of our apps.py module
    def ready(self):
        import users.signals

However, upon the creation of a new User there is still no associated Profile object. Any idea why this is not working?


Solution

  • UsersConfig.ready() never runs and thus your signals are not seen by Django

    Solutions

    1. Add users.apps.UsersConfig to your INSTALLED_APPS

    OR

    1. Add default_app_config = 'users.apps.UsersConfig' in your __init__.py

    OR

    1. Just add your signals directly in your models.py

    Checkout: https://docs.djangoproject.com/en/2.2/ref/applications/