EDIT: If you want to skip the background story and just check the error message and code dump it's all at the bottom :)
I've been trying to implement a user-registration form for half a day now and feel that I'm sooo close but not quite there yet.
So I started out by implementing Django's built in UserCreationForm
. And for my view I cunstructed this piece of code inspired by a response to this question:
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login
def create_user(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = User.objects.create_user(**form.cleaned_data)
login(new_user)
return redirect('post_list')
else:
form = UserCreationForm()
return render(request, 'blog/create_user.html', {'form': form})
Problem was: I wanted the users to be able to store their email as well. So I decided to use a piece of code from this blog to extend the UserCreationForm()
in the forms.py
file:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserCreateForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ("username", "email", "password1", "password2")
def save(self, commit=True):
user = super(UserCreateForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
if commit:
user.save()
return user
It still refused to include the email-part when I checked the actual web-page (even after I switched out: from django.contrib.auth.forms import UserCreationForm
to from .forms import UserCreationForm
). Finally I switched names in my forms.py file to UserForm in both the views.py
and the forms.py
files. So in the forms.py
file it now said:
class UserForm(UserCreationForm):
Solution inspired by this question.
So now it said 'password1' is an invalid keyword argument for this function
, I thought "of course, I'm passing a dictionary from my form into create_user and now that I've tampered with UserCreationForm
it doesn't run as smoothly any more: create_user wants to have a username, email and password right? But now I'm sending username, email, password1 and password2.
So I added the following to the code in views.py
:
if form.is_valid():
username = form.cleaned_data["username"]
email = form.cleaned_data["email"]
password = form.cleaned_data["password1"]
new_user = User.objects.create_user(username, email, password)
login(new_user)
So now I get TypeError at /create_user/: login() takes exactly 2 arguments (1 given)
and what really grinds my gears is how this wasn't an issue before I tampered with UserCreationForm
(to the best of my recollection). But alright, alright, I'll google it, read through the documentation and some examples, looks like most people call the login-function with login(request, user)
so I change my code again to:
new_user = User.objects.create_user(username, email, password)
login(request, new_user)
And here, I'm finally at an impasse as I get:
'User' object has no attribute 'backend'
I google it and either I don't find anything that correlates with my situation or I'm to slow witted to see that it does. If there's anyone out there who can explain what's wrong I would greatly appreciate it.
Code dump of current code:
Omitted other views and unrelated imports for readability
views.py
from django.shortcuts import render
from .forms import UserForm
from django.shortcuts import redirect
from django.contrib.auth.models import User
from django.contrib.auth import login
def create_user(request):
if request.method == "POST":
form = UserForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
email = form.cleaned_data["email"]
password = form.cleaned_data["password1"]
new_user = User.objects.create_user(username, email, password)
login(new_user)
return redirect('post_list')
else:
form = UserForm()
return render(request, 'blog/create_user.html', {'form': form})
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ("username", "email", "password1", "password2")
def save(self, commit=True):
user = super(UserForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
if commit:
user.save()
return user