I am aware of this answer: TypeError: get_session_auth_hash() missing 1 required positional argument: 'self', but I am not using a custom backend and the error in question happens when registering a new user through a Django form, not when logging in.
Further, whilst the user does not remain logged in when registering and is not automatically redirected to the main page as intended, logging in from the log in form seems to function normally.
The error happens on this line in my registration view: login(request, User)
And traces back to this line in django.contrib.auth:
if user is None:
user = request.user
if hasattr(user, 'get_session_auth_hash'):
session_auth_hash = user.get_session_auth_hash() <<<<<<<<< This line
I think because I'm using a custom user, there's something else I need to modify in the default code, but I'm not sure what this should be. I think the custom user model should be interchangeable with the default user model, but it isn't and I'd welcome someone with more experience than me pointing me in the right direction.
My code as follows:
Custom user model and manager in models.py
:
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class UserManager(BaseUserManager):
def create_user(self, email, password = None, active = True, staff = False, superuser = False):
if not email:
raise ValueError('Users must have an email')
if not password:
raise ValueError('Users must have a password')
user = self.model(email = self.normalize_email(email))
user.set_password(password)
user.staff = staff
user.superuser = superuser
user.active = active
user.save(using=self._db)
return user
def create_staffuser(self, email, password = None):
user = self.create_user(email, password = password, staff = True)
return user
def create_superuser(self, email, password = None):
user = self.create_user(email, password = password, staff = True, superuser = True)
return user
class User(AbstractBaseUser):
user_id = models.AutoField(primary_key=True)
email = models.EmailField(max_length = 255, unique =True, default = 'abc123@domain.ext')
active = models.BooleanField(default = True)#can login
staff = models.BooleanField(default = False)#staff user non superuser
superuser = models.BooleanField(default = False)#superuser
USERNAME_FIELD = 'email' #to set username
#username and passwor fields are required by default
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return (str(self.user_id) + ' ' + ' ' + self.email)
def has_perm(self, perm, obj=None):
return self.superuser
def has_module_perms(self, app_label):
return self.superuser
@property
def is_staff(self):
return self.staff
@property
def is_superuser(self):
return self.superuser
@property
def is_active(self):
return self.active
Registration view in views.py
:
from .models import User
from .forms import NewUserForm
def register_request(request):
if request.method == "POST":
form = NewUserForm(request.POST)
if form.is_valid():
user = form.save()
login(request, User)
messages.success(request, "Registration successful." )
return redirect("main:homepage")
messages.error(request, "Unsuccessful registration. Invalid information.")
form = NewUserForm()
return render (request=request, template_name="main/register.html", context={"register_form":form})
forms.py
from django.contrib.auth.forms import UserCreationForm
from .models import User
class NewUserForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ("email", "password1", "password2")
def save(self, commit=True):
user = super(NewUserForm, self).save(commit=False)
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
Please tell me if there's anything else you need to see. Please forgive me if this question is answered elsewhere here, but I have looked, and not just at the link above! Thanks in advance.
Note: Tried replacing
from .models import User
with:
from django.contrib.auth import get_user_model
User = get_user_model()
in all modules which utilises User model. Same error occurs at same locations.
You've got a typo in login
. You are using User
which is the class instead of user
:
login(request, User) # --> should be login(request, user)