I have implemented a custom user setup for django 2. However I can't seem to find out source of this error that occurs anytime I attempt to register.
AttributeError at /register/
'AnonymousUser' object has no attribute '_meta'
When I get this error, the password is passed without a hash and not saved to the db, while the other values pass through fine.
models.py
from django.db import models
from django.contrib.auth.models import BaseUserManager
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import ugettext_lazy as _
class MyUserManager(BaseUserManager):
def _create_user(self, email, password):
if not email:
raise ValueError('The Email must be set')
email = self.normalize_email(email)
user = self.model(email=email,)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(email, password)
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, null=True)
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this site.'),
)
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this user should be treated as active. '
'Unselect this instead of deleting accounts.'
),
)
USERNAME_FIELD = 'email'
objects = MyUserManager()
def __str__(self):
return self.email
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
views.py
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.forms import UserCreationForm, PasswordChangeForm
from django.contrib import messages
from . forms import RegisterForm
def home(request):
return render(request, 'authenticate/home.html', {})
def login_user(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
messages.success(request, ('Welcome Back'))
return redirect('home')
else:
messages.success(request, ('No account matches those credentials. Please try again.'))
return redirect('login')
else:
return render(request, 'authenticate/login.html', {})
def logout_user(request):
logout(request)
messages.success(request, ('Successfully logged out'))
return redirect('home')
def register_user(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data['email']
password = form.cleaned_data['password1']
user = authenticate(email=email, password=password)
login(request, user)
messages.success(request, ('Welcome to Keto2Go!'))
return redirect('home')
else:
form = RegisterForm()
context = {'form': form}
return render(request, 'authenticate/register.html', context)
def edit_profile(request):
if request.method == 'POST':
form = UserChangeForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
messages.success(request, ('You have updated your profile'))
return redirect('home')
else:
form = UserChangeForm(instance=request.user)
context = {'form': form}
return render(request, 'authenticate/edit_profile.html', context)
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
messages.success(request, ('Your password has been updated.'))
return redirect('home')
else:
form = PasswordChangeForm(user=request.user)
context = {'form': form}
return render(request, 'authenticate/change_password.html', context)
forms.py
from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from . models import User
class RegisterForm(forms.ModelForm):
password1 = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(label='Confirm password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email',)
def clean_email(self):
email = self.cleaned_data.get('email')
qs = User.objects.filter(email=email)
if qs.exists():
raise forms.ValidationError("email is taken")
return email
def clean_password2(self):
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data and self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError("The password does not match ")
return self.cleaned_data
class UserAdminCreationForm(forms.ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email',)
def clean_password2(self):
# Check that the two password entries match
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data and self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError("The password does not match ")
return self.cleaned_data
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserAdminChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField()
class Meta:
model = User
fields = ('email', 'password')
def clean_password(self):
return self.initial["password"]