Search code examples
pythondjangomodeldjango-signals

why signal triggered in wrong time?


I'm creating a signal which creates a profile for the user considering the group they are in. For example if they user is in TEACHER group the teacher_profile would be created for it.

The problem is that the signal triggered before the group of user has been set and gives me the error 'NoneType' object has no attribute 'name'.

#views.py
def register_page(request):
    if request.POST:
        password = request.POST['password']
        repassword = request.POST['repassword']
        username = request.POST['username']
        GROUP = request.POST['group']
        if password == repassword:
            #creating user
            user = User.objects.create(is_superuser=False, username=username)
            user.groups.set([Group.objects.get(name=GROUP), ])
            user.set_password(password)
            user.save()
            
            #authenticating user
            user = authenticate(username=username, password=password)
            if user:
                login(request, user)
                return redirect('/esadra/user/dashboard/')
        else:
            messages.error(request, 'پسورد ها مطابقت ندارند')
#models.py

@receiver(post_save, sender=User)
def user_profile_creator(sender, instance, created, *args, **kwargs):
    if created:
        if instance.groups.first().name == 'TEACHER':
            profile = teacher.objects.create(user=instance)
        elif instance.groups.objects.first().name == 'Student':
            profile = student.objects.create(user=instance)

I have tried m2m_changed that made other problems for set_password , it made the user instance None type because it should be saved to trigger the m2m_changed signal.

Every answer would be appreciated.


Solution

  • You might try to accomplish it straight away in the view

    def register_page(request):
        if request.POST:
            password = request.POST['password']
            repassword = request.POST['repassword']
            username = request.POST['username']
            GROUP = request.POST['group']
            if password == repassword:
                #creating user
                group = Group.objects.get(name=GROUP)
                user = User.objects.create(is_superuser=False, username=username)
                user.groups.set([group, ])
                user.set_password(password)
                user.save()
                if group.name == 'TEACHER':
                    teacher.objects.create(user=user)
                elif group.name == 'Student':
                    student.objects.create(user=user)
                
                #authenticating user
                user = authenticate(username=username, password=password)
                if user:
                    login(request, user)
                    return redirect('/esadra/user/dashboard/')
            else:
                messages.error(request, 'پسورد ها مطابقت ندارند')
    

    additionally if you want to make it more readable or so, just extract it into separate funcs etc.

    Will that do the trick for you ?