在Django注册后如何自动登录用户


74

这是我目前用于注册的内容:

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))

是否可以不要求用户在创建帐户后手动登录,而是简单地自动登录?谢谢。

编辑:我曾尝试过login()函数,但没有成功。我相信问题是未设置AUTHENTICATION_BACKENDS。


Answers:


108

使用authenticate()login()功能:

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/")

1
谢谢。我曾经尝试过,但是没有成功,但是现在我意识到问题是我没有指定后端。这些行:new_user.backend ='django.contrib.auth.backends.ModelBackend'login(request,new_user)完成了任务。(还是应该在其他地方而不是每次进行注册时指定后端?)
克里斯(Chris

2
设置AUTHENTICATION_BACKENDSdjango.contrib.auth.backends.ModelBackendsettings.py。有关更多信息,请参阅docs.djangoproject.com/en/1.2/topics/auth/…
David Antaramian 2010年

3
嗯,您必须先打电话,authenticate()否则没有backend设置。我已经更新了答案以显示这一点。
本·詹姆斯

2
使我绊倒​​的另一件事是,authenticateing时必须使用原始字符串。我试图变得聪明,将其从原始new_user对象中偷偷偷偷溜走,但是我想它附带了一些字段引用。也就是说,不要这样做:new_user = authenticate(username = new_user.username, password = new_user.password)而是从POST代码段描述中的或从中获取它们form
Alex Beynenson 2011年

11
工作完美。如果在验证期间由于某些原因修改了POST数据,则最好直接使用经过验证的表单的字段而不是POST数据。new_user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'])
帕特里克

9

对于基于类的视图,这里是对我有用的代码(最初是Django 1.7,已更新为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)

为什么authenticate(username=username, password=password)需要?为什么不仅仅传递用户对象?
avi

1
@avi手动登录用户时,必须在调用login()之前使用authenticate()成功认证用户。authenticate()在User上设置一个属性,该属性指示哪个身份验证后端已成功对该用户进行身份验证(有关详细信息,请参阅后端文档),此信息在稍后的登录过程中需要。如果您尝试直接登录从数据库检索的用户对象,将引发错误。来源:docs.djangoproject.com/en/1.9/topics/auth/default/...
f1nn

这在Django 2.1.4中无法立即使用,我不得不使用另一种return使用redirect,请参阅单独的[question](stackoverflow.com/questions/54179736/…
sc28

1
@ sc28我已经更新了答案,可以在更高版本的Django中使用。
Alasdair

0

您可以继承Django的UserCreationForm,并覆盖它的save方法以在commit = True时将其登录。

表格

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

您只需要确保在实例化表单时传递请求对象。您可以通过重写视图的get_form_kwargs方法来实现。

views.py

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

或者,确保在实例化form_class时执行CustomUserCreationForm(data=request.POST, request=self.request)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.