Search code examples
djangodjango-modelsdjango-admindjango-signals

Post save signal fires before create super user function


i have got stuck into some unusual problem where is need to create profiles based on the different user types eg .super must not have a profile while other users can have the profile

i have my own user model which extends the base user manager

class MyUserManager(BaseUserManager):
    def create_user(self, username=None, email=None, password=None):
        """
        Creates and saves a User with the given username, email and password.
        """
        if not username:
            raise ValueError('Must include username')

        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            username = username,
            email = self.normalize_email(email),
            gender='MALE',
        )

        user.set_password(password)
        user.save(using=self._db) 
        print user
        return user

    def create_superuser(self, username, email,  password):
        """
        Creates and saves a superuser with the given username, email and password.
        """

        user = self.create_user(
            username=username,
            email=email,
            password=password,
        )
        user.is_admin = True
        print user, user.is_admin
        user.save(using=self._db)
        return user

and then using the below signal i create profiles

def new_user_receiver(sender, instance, created, *args, **kwargs):
    if not instance.is_admin:
        print instance , instance.is_admin , not instance.is_admin
        new_profile, is_created = UserProfile.objects.get_or_create(user=instance)
    else:
        pass

post_save.connect(new_user_receiver, sender=MyUser)

The problem i am facing right now is this that the above signal gets fired as soon as user is created and the profile is created for the super user as well

Is there a way by which i can avoid creating profiles for superusers?

Thank you.


Solution

  • The reason why profile will be created for admin is because you use create_user in create_superuser. At first an normal user will be saved. Here the profile is created for every one. At twice this user will be modified to admin. You should call this in your create_superuser function:

     def create_user(self, username=None, email=None, password=None, is_admin=False):
            """
            Creates and saves a User with the given username, email and password.
            """
            if not username:
                raise ValueError('Must include username')
    
            if not email:
                raise ValueError('Users must have an email address')
    
            user = self.model(
                username = username,
                email = self.normalize_email(email),
                gender='MALE',
                is_admin = is_admin,
            )
    
            user.set_password(password)
            user.save(using=self._db) 
            print user
            return user
    
        def create_superuser(self, username, email,  password):
            """
            Creates and saves a superuser with the given username, email and password.
            """
    
            user = self.create_user(
                username=username,
                email=email,
                password=password,
                is_admin = True,
            )
            return user
    

    OR

    if instance.is_admin: UserProfile.objects.filter(user=instance).delete()

    after if not instance.is_admin ... but this way is not elegant