User Registration and Profile

Hey guys. I have been struggling with an issue for a couple of days and I think the answer may be to create a custom User model and custom Manager but would like to see if I can avoid that for now. What I am trying to do is register a user and have them fill out some profile information at the same. I keep running into the error ‘‘AnonymousUser’ object has no attribute ‘_meta’’ whenever I am not logged in as Admin. I am confused why I would need to be logged in to create a new account, hence why I am here.

Models.py

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    branch = models.CharField(max_length=50, blank=True)
    region = models.CharField(max_length=30, blank=True)
    # birth_date = models.DateField(null=True, blank=True)

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

    @receiver(post_save, sender=User)
    def save_user_profile(sender, instance, **kwargs):
        # print("save",sender, instance,**kwargs)
        instance.profile.save()

Forms.py

from .models import EmployeeDifferentLocation, Profile
from django.contrib.auth.models import User

# create a ModelForm

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email')

class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = '__all__'
        exclude = ['user']

Views.py

from django.shortcuts import render, redirect
from .forms import EmployeeLocation, UserForm, ProfileForm
from .models import EmployeeDifferentLocation
from .filters import EmployeeFilter
from django.contrib.auth.decorators import login_required

def create_profile(request):
    print(request)
    if request.method == "POST":
        user_form = UserForm(request.POST, instance=request.user)
        profile_form = ProfileForm(request.POST, instance=request.user.profile)
        if user_form.is_valid() and profile_form.is_valid():
            user =user_form.save(commit=False)
            profile = profile_form.save()
            profile.user = user

            profile.save()
            user.save()
            # messages.success(request,('Your profile was successfully updated!'))
            return render(request,'home.html')
    user_form = UserForm(instance=request.user)
    profile_form = ProfileForm(instance=request.user.profile)
    return render(request, 'profile.html',{'user_form':user_form, 'profile_form':profile_form})

I am wanting a user to fill out what their ‘Region’ and ‘Branch’ would be as they are registering their new user account is my end goal. I have watched videos on how to create custom user models and managers and may just have to go that route. Can someone explain to me why I am needing to be logged in to register a new account?

Any help would be greatly appreciated. Thanks!

Without seeing the complete traceback, I’m going to guess that the error is referencing this line:

The issue here is that the AnonymousUser is not a User! It’s more like a “pseudo-user” object created for explicitly handling requests from not-logged-in users. The problem is created because you’re trying to refer to the profile field of request.user - but in this case, request.user is not a user having a profile field.

A side note - you’re not altering the User object after calling the .save method on User_form - there’s no reason for you to use the commit=False parameter on that call. It’s the profile object being modified after saving the form, so that’s the call that should contain that parameter.

Thank you for pointing that out, I have changed commit = False to be with the Profile and not the User. I have made some adjustments to the creatae_profile function in views.py. The second and third to last lines were modified (it was giving an error) so I removed the arguments from them. Now the traceback is:

Traceback (most recent call last):
  File "C:\Users\WindowsUser\Documents\Python Projects\virtualenvironments\djangoUFCU\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\WindowsUser\Documents\Python Projects\virtualenvironments\djangoUFCU\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\WindowsUser\Documents\Python Projects\mysite\RetailGoals\views.py", line 30, in create_profile
    user_form = UserForm(request.POST, instance=request.user)
  File "C:\Users\WindowsUser\Documents\Python Projects\virtualenvironments\djangoUFCU\lib\site-packages\django\forms\models.py", line 302, in __init__
    object_data = model_to_dict(instance, opts.fields, opts.exclude)
  File "C:\Users\WindowsUser\Documents\Python Projects\virtualenvironments\djangoUFCU\lib\site-packages\django\forms\models.py", line 85, in model_to_dict
    opts = instance._meta
  File "C:\Users\WindowsUser\Documents\Python Projects\virtualenvironments\djangoUFCU\lib\site-packages\django\utils\functional.py", line 247, in inner
    return func(self._wrapped, *args)

Exception Type: AttributeError at /goals/register/
Exception Value: 'AnonymousUser' object has no attribute '_meta'

Views.py

def create_profile(request):
    print(request)
    if request.method == "POST":
        user_form = UserForm(request.POST, instance=request.user)
        profile_form = ProfileForm(request.POST, instance=request.user.profile)
        if user_form.is_valid() and profile_form.is_valid():
            user =user_form.save()
            profile = profile_form.save(commit=False)
            profile.user = user
            profile.save()
            user.save()
            return render(request,'home.html')
    user_form = UserForm()
    profile_form = ProfileForm()
    return render(request, 'profile.html',{'user_form':user_form, 'profile_form':profile_form})

Since AnonymousUser isnt a real user, should I allow them to register a user first and them redirect them to a profile form? That could solve this issue.

You still have the same issue here (line 5 of the posted snippet). The request.user object does not have a profile attribute for AnonymousUser.

Thank you! I will look into this more. I appreciate your time and help