How to automatically login a user after registration in django

This is what I am currently using for registration:

def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
messages.info(request, "Thanks for registering. Please login to continue.")
return HttpResponseRedirect("/dashboard/")
else:
form = UserCreationForm()
return render_to_response("accounts/register.html", {
'form': form,
}, context_instance=RequestContext(request))

Is it possible not to require the user to login manually after creating an account, but rather simply to log them in automatically? Thanks.

edit: I had tried the login() function without success. I believe the problem is that AUTHENTICATION_BACKENDS was not set.

36402 次浏览

Using the authenticate() and login() functions:

from django.contrib.auth import authenticate, login


def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
messages.info(request, "Thanks for registering. You are now logged in.")
new_user = authenticate(username=form.cleaned_data['username'],
password=form.cleaned_data['password1'],
)
login(request, new_user)
return HttpResponseRedirect("/dashboard/")

for class based views here was the code that worked for me (originally Django 1.7, updated for 2.1)

from django.contrib.auth import authenticate, login
from django.contrib.auth.forms import UserCreationForm
from django.http import HttpResponseRedirect
from django.views.generic import FormView


class SignUp(FormView):
template_name = 'signup.html'
form_class = UserCreateForm
success_url='/account'


def form_valid(self, form):
#save the new user first
form.save()
#get the username and password
username = self.request.POST['username']
password = self.request.POST['password1']
#authenticate user then login
user = authenticate(username=username, password=password)
login(self.request, user)
return HttpResponseRedirect(self.get_success_url)

You can subclass Django's UserCreationForm and override it's save method to log them in when commit=True.

forms.py

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login


class CustomUserCreationForm(UserCreationForm):
"""
A ModelForm for creating a User and logging
them in after commiting a save of the form.
"""


def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs)
self.request = request


class Meta(UserCreationForm.Meta):
pass


def save(self, commit=True):
user = super().save(commit=commit)
if commit:
auth_user = authenticate(
username=self.cleaned_data['username'],
password=self.cleaned_data['password1']
)
login(self.request, auth_user)


return user

You just need to make sure you pass in a request object when you instantiate the form. You can do that by overriding the view's get_form_kwargs method.

views.py

def get_form_kwargs(self):
form_kwargs = super().get_form_kwargs()
form_kwargs['request'] = self.request
return form_kwargs


Or, make sure when you instantiate a form_class you do CustomUserCreationForm(data=request.POST, request=self.request).

The accepted answer doesn't seem to work with Django 4.0 (for me, at least), or alternatively it doesn't work with custom user models that have custom user managers.

This is how I solved the issue (adapted from https://stackoverflow.com/a/31491942 and https://stackoverflow.com/a/68515276):

from django.views.generic import CreateView
from django.urls import reverse_lazy
from django.contrib.auth import authenticate, login
from your.custom.user.models import User


class SignUpView(CreateView):
model = User
fields = ["username", "email", "password"]
success_url = reverse_lazy("success_url_name") # change this with your own URL


def form_valid(self, form):
# create the user object
user = form.save(commit=False)
# set password manually
# as otherwise the User will be saved with unhashed password
user.set_password(form.cleaned_data.get("password"))
# save your User object to the database
user.save()
# get email and password
email = form.cleaned_data.get("email")
password = form.cleaned_data.get("password")
# authenticate your user with unhashed password, because `authenticate` hashes it again
authenticated_user = authenticate(email=email, password=password)
# log in
login(self.request, authenticated_user)
return redirect(self.success_url)

You need to manually set the password, so that the database contains the hashed password. Without that, your unhashed password will be saved to the database, which will prevent you from logging in afterwards, as authentication involves hashing the password and checking that against the database.

using only "login()" in django-4.0.3

from django.contrib.auth import login


def registration(request):
if request.POST:
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
username = form.cleaned_data.get('username')
messages.success(request, f'Account created for {username}')
        

return redirect('home')

The Django auth.login function makes it easy to log in a user, given a request and User instance.

Note: remember to add the necessary imports for the following examples.

from django.contrib.auth import login
from django.shortcuts import render, redirect

In a function-based view, the following should work.

if form.is_valid():
user = form.save()


login(request, user)


return redirect("desired-url")

For a class-based view (such as CreateView or FormView), you can override the form_valid method:

def form_valid(self, form):
"""If the form is valid, save the associated model and log the user in."""
user = form.save()
login(self.request, user)


return redirect(self.success_url)