djangodjango-modelsdjango-viewsdjango-signalsdjango-errors

AttributeError on signals.py when combine user and profile


after combined User with Custom Profile on the register template forms included with signals.py to synchronization with User models. The knowledge base was given the solution to add related_name to the models.py on OnetoOneFiedld and the issue still remains.

    AttributeError at /createuser
'User' object has no attribute 'profile'
Request Method: POST
Request URL:    http://127.0.0.1:8000/createuser
Django Version: 3.1.2
Exception Type: AttributeError
Exception Value:    
'User' object has no attribute 'profile'
Exception Location: D:\Dev\main0\main\accounts\signals.py, line 16, in update_profile
Python Executable:  D:\Dev\main0\venv\Scripts\python.exe
Python Version: 3.8.5
Python Path:    
['D:\\Dev\\main0\\main',
 'D:\\Dev\\main0\\venv\\Scripts\\python38.zip',
 'c:\\python38\\DLLs',
 'c:\\python38\\lib',
 'c:\\python38',
 'D:\\Dev\\main0\\venv',
 'D:\\Dev\\main0\\venv\\lib\\site-packages']
Server time:    Sun, 01 Nov 2020 14:34:42 +000

I try to find out what is the root cause for an error Here is the Signals.py file

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


@receiver(post_save, sender=User) 
def update_profile(sender, instance, created, **kwargs):
    if created == False:
        instance.profile.save()

and the views.py

def CreateUser(request):
if request.method == 'POST':
    first_name = request.POST['first_name']
    last_name = request.POST['last_name']
    username = request.POST['username']
    password = request.POST['password1']
    repassword = request.POST['password2']
    email = request.POST['email']

    if password == repassword:
        if User.objects.filter(username=username).exists():
            messages.error(request, f'User {username} already existed!!!')
            return redirect('register-page')
        elif User.objects.filter(email=email).exists():
            messages.error(request, f'email {email} already existed!!!')
            return redirect('register-page')
        else:
            user = User.objects.create_user(
                username=username, 
                password=password, 
                email=email, 
                first_name=first_name, 
                last_name=last_name
                )
            user.save()
            profile = Profile.objects.create(
                gender=gender,
                date_of_birth=date_of_birth,
                phone_number=phone_number,
                photo=photo
                )
            profile.user = user
            profile.save()           
            messages.success(request, f'User {username} has been created successfully!!')
            return redirect('main-users-page')
    else:
        messages.info(request,'password does not match')
        return redirect('register-page')
else:
    return render(request, 'registration/register.html')

Solution

  • the solution to add detail on signals.py

        @receiver(post_save, sender=User) 
    def create_profile(sender, instance, created, **kwargs):
        if created:
            Profile.objects.create(user=instance)
            
    
        post_save.connect(create_profile, sender=User)
        
        @receiver(post_save, sender=User) 
        def update_profile(sender, instance, created, **kwargs):
            if created == False:
                instance.profile.save()
                print('Profile updated!!')
        
        post_save.connect(update_profile, sender=User)