I am trying to make a class-based registration view equivalent of my old function based registration view. When I register as a new user, a user is created but is not logged in after registration, and this bug only happens when I use class-based registration view. Form doesn't return any errors also.
views.py class-based (doesn't log in after registration)
from django.contrib import messages
from django.contrib.auth import login
from django.urls import reverse_lazy
from django.views.generic import CreateView
from .forms import NewUserForm
class RegisterUserView(CreateView):
form_class = NewUserForm
success_url = reverse_lazy('home')
template_name = 'users/register.html'
def form_valid(self, form):
user = form.save()
login(self.request, user)
return super().form_valid(form)
def form_invalid(self, form):
messages.error(self.request, form.errors)
return super().form_invalid(form)
views.py function-based (does log in after registration)
from django.contrib import messages
from django.contrib.auth import login
from django.shortcuts import redirect, render
from .forms import NewUserForm
def register_user(request):
if request.method == "POST":
form = NewUserForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect('home')
messages.error(request, form.errors)
form = NewUserForm(request.POST)
context = {
"form": form
}
return render(request, "users/register.html", context)
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
email = models.EmailField(unique=True)
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser
class NewUserForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = CustomUser
fields = ["username", "email", "password1", "password2"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.label_suffix = "" # Removes ':' as label suffix
self.fields['username'].help_text = 'Letters, numbers and @/./+/-/_ only.'
self.fields['password1'].help_text = '8-20 characters, letters and numbers, no spaces.'
self.fields['password2'].help_text = None
def save(self, commit=True):
user = super(NewUserForm, self).save(commit=False)
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
settings.py
AUTH_USER_MODEL = "users.CustomUser"
I managed to fix this by simply changing CreateView to FormView.
class RegisterUserView(FormView):
form_class = NewUserForm
success_url = reverse_lazy('home')
template_name = 'users/register.html'
def form_valid(self, form):
form.save()
new_user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password1'])
login(self.request, new_user)
return super().form_valid(form)
def form_invalid(self, form):
messages.error(self.request, form.errors)
return super().form_invalid(form)
I also added authenticate() to authenticate the user after creating account to prevent any issues with user authentication.