4
votes

I have the following register view that enters a new user. I want it to enter the new user and then log in automatically. It saves through the User record but returns this error when trying to login: 'AnonymousUser' object has no attribute 'backend'

views.py

def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST, error_class=DivErrorList)
        if form.is_valid():
            form.save()
            new_user = authenticate(username=request.POST['username'],password=request.POST['password'])
            login(request, new_user)
            return HttpResponseRedirect('/production/')
    else:
        form = UserRegisterForm(error_class=DivErrorList)

    return render(request,'register.html', {
        'form': form,
    })

forms.py

class UserRegisterForm(forms.ModelForm):

    class Meta:
        model = User
        fields = ('username','first_name','last_name','email','password')

    password_compare = forms.CharField(max_length=128)

    def __init__(self, *args, **kwargs):
        super(UserRegisterForm, self).__init__(*args, **kwargs)
        self.fields['password_compare'].label = 'Password Again'
        self.fields['password'].help_text = ''
        self.fields['first_name'].label = 'First Name'
        self.fields['last_name'].label = 'Last Name'
        self.fields['email'].label = 'E-mail Address'

    def clean(self):
        cleaned_data = self.cleaned_data
        password1 = cleaned_data.get('password', None)
        password2 = cleaned_data.get('password_compare', None)
        if not (password1):
            error_msg = u'This field is required.'
            self._errors['password'] = self.error_class([error_msg])
        if not (password2):
            error_msg = u'This field is required.'
            self._errors['password_compare'] = self.error_class([error_msg])
        # password fields must match
        if password1 != password2:
            error_msg = u'Password doesn\'t match the confirmation.'
            self._errors['password'] = self.error_class([error_msg])
            del cleaned_data['password']
        # cannot have a username already existing
        try:
            existing_user = User.objects.get(username=cleaned_data.get('username'))
            error_msg = u'Username already exists.'
            self._errors['username'] = self.error_class([error_msg])
            del cleaned_data['username']
            return cleaned_data
        except User.DoesNotExist:
            return cleaned_data
2

2 Answers

6
votes

Your user will never authenticate, because you're saving the password in plain text - and authenticate expects a hashed password. You should call user.set_password(password) on the newly-created user object before saving it to the db - see the built-in UserCreationForm.

0
votes

I had the same error for a newly registering user and it left me frustrated for an hour.

There was a piece of code that tried to log user in right after the registration.
Usually it worked just fine, but not this time.

def attempt_login(self, email, password):
    user = authenticate(username=email, password=password)
    login(self.request, user)

    return user 

It seemed that authenticate returned None, and then calling login with None caused this exception. But I was sure the User has been created after registration.

Finally, I realized that this particular user's login was longer than 30 characters, and the form field had no validation. The login would get truncated in the database, and therefore authenticate was called for non-existent login.