Search code examples
pythondjangosignals

Issue with creating different profiles in Django signals


I'm facing an issue in my Django application where I need to create different profiles, either Profile1 or Profile2, based on the value of user.is_manager. I'm utilizing signals to handle this logic.

Here is a summary of the problem:

  • I have two profile models: Profile1 and Profile2. Profile1 is intended for manager users, while Profile2 is for non-manager users.

  • In my managers.py file, I set user.is_manager to True for manager users during the creation of a user.

  • However, when I try to access instance.is_manager in my signals.py file, it consistently returns False, even though it should be True according to the value set in managers.py.

The is_manager field is correctly set to True in the database but is still False during the signal handling

Any suggestions or insights to resolve this issue would be greatly appreciated.

# managers.py

from django.contrib.auth.models import BaseUserManager


class UserManager(BaseUserManager):
    def create_user(self, phone, username, email, password):
        user = self.model(phone=phone, username=username, email=email)
        user.set_password(password)
        user.save(using=self.db)
        return user

    def create_superuser(self, phone, username, email, password):
        user = self.create_user(phone, username, email, password)
        user.is_admin = True
        user.is_manager = True # when create a superuser it's a manager too
        user.save(using=self.db)
        return 
# apps.py

from django.apps import AppConfig


class PanelConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'panel'

    def ready(self):
        import panel.signals
# signals.py

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings

from .models import User
from accounts.models import Profile1, Profile2


@receiver(post_save, sender=User, dispatch_uid="panel.signals.create_profile")
def create_profile(sender, instance, created, **kwargs):
    if created:
        if instance.is_manager: # this returns False
            profile = Profile1.objects.create(user=instance)
        else:
            profile = Profile2.objects.create(user=instance)
            
        profile.save()

I have already reviewed my code and verified that user.is_manager is correctly set to True in managers.py. I'm looking for guidance on why the value of instance.is_manager is not being captured accurately in the signals.


Solution

  • Go with this code no need to signal it's very straight forward...

    class UserManager(BaseUserManager):
        use_in_migrations = True
    
        def _create_user(self,username, email, phone, password, **extra_fields):
            values = [email]
            field_value_map = dict(zip(self.model.REQUIRED_FIELDS, values))
            for field_name, value in field_value_map.items():
                if not value:
                    raise ValueError("The {} value must be set".format(field_name))
    
            email = self.normalize_email(email)
            user = self.model(email=email, username=username, phone=phone, **extra_fields)
            user.set_password(password)
            user.save(using=self._db)
            # Profile creating here...
            if user.is_manager: 
                profile = Profile1.objects.create(user=user)
            else:
                profile = Profile2.objects.create(user=user)
            return user
    
        def create_user(self, email, username, phone, password=None, **extra_fields):
            extra_fields.setdefault("is_staff", False)
            extra_fields.setdefault("is_superuser", False)
            return self._create_user(email,username, phone, password, **extra_fields)
    
        def create_superuser(self, email, username, phone, password=None, **extra_fields):
            extra_fields.setdefault("is_staff", True)
            extra_fields.setdefault("is_superuser", True)
            if extra_fields.get("is_staff") is not True:
                raise ValueError("Superuser must have is_staff=True.")
            if extra_fields.get("is_superuser") is not True:
                raise ValueError("Superuser must have is_superuser=True.")
    
            return self._create_user(email, username, phone, password, **extra_fields)