How to automatically create user profile for new users that register to the platform in Django

Viewed 3676

I have created a models file with custom user model and employeeProfile with details for the employee profile, a signal file to automatically create a profile for new user. Although i have set this up, new users profile is not created automatically forcing me to add them manually in the admin page. Kindly assist with a solution.

models.py file looks like this

(...) # imports
class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=255, unique=True)
    name = models.CharField(max_length=255)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    date_joined = models.DateTimeField(
        default=datetime.now, blank=True)  # To add then run migrations

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name']  # email is already required, no need to add

    def get_full_name(self):
        return self.name

    def get_short_name(self):
        return self.name

    def __str__(self):
        return self.email


# Employees profile
class employeeProfile(models.Model):
    user = models.OneToOneField(
        CustomUser, on_delete=models.CASCADE, related_name="profile")
    description = models.TextField(blank=True, null=True)
    location = models.CharField(max_length=30, blank=True)
    Department = models.CharField(max_length=30, blank=True)
    Job_title = models.CharField(max_length=30, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
    is_manager = models.BooleanField(default=False)

    def __str__(self):
        return self.user.name

CustomUserManager file

class CustomUserManager(BaseUserManager):

    def create_user(self, email, name, password=None):
        if not email:
            raise ValueError("Users must have an email address")

        email = self.normalize_email(email)
        user = self.model(email=email, name=name)

        user.set_password(password)
        user.save()

        return user

    def create_superuser(self, email, name, password):
        user = self.create_user(email, password)

        user.is_superuser = True
        user.is_staff = True
        user.save()

        return user

Signal.py file

(...) # other imports
from django.contrib.auth import get_user_model
User = get_user_model()

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        employeeProfile.objects.create(user=instance)

NB: I have registered my signal in accounts

from django.apps import AppConfig

class AccountsConfig(AppConfig):
    name = 'accounts'

    def ready(self):
        import accounts.signals
2 Answers

If you setup your signal properly it should suffice your requirement.

The proper setup of signal is you have to update the apps.py

e.g:

apps.py

class MyAppConfig(AppConfig):
  name='myapp'

  def ready(self):
     # import your signal file in here if the app is ready
     from . import receivers

finally update the app init.py, by importing your apps.py:

e.g.

default_app_config='myapp.apps.MyAppConfig'

In your signals, I think the sender should be the CustomUser. That is whenever an instance of the CustomUser is created, then we should create an employeeProfile.

Only after the CustomUser is created should we then be able to use get_user_model as only at that moment do we have an active user.

Try your signal code like this (of course with the correct path to your models):

from models import CustomUser

@receiver(post_save, sender=CustomUser)
def create_profile(sender, instance, created, **kwargs):
    if created:
        employeeProfile.objects.create(user=instance)
Related