代码改变世界

130-注册和登录的相关反馈,比较拙劣的做法,请大牛给予建议

2020-08-30 17:14  lzhshn  阅读(328)  评论(0编辑  收藏  举报

主要在views函数里进行判断,然后使用messages在模板中将相关信息显示出来。

 

from django.shortcuts import render, get_object_or_404, reverse
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from .models import ExUser
from .forms import UserLoginForm, UserRegForm
from django.contrib import messages



def user_login(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        login_user = authenticate(request, username=username, password=password)

        if login_user is not None:
            login(request, login_user)
            return HttpResponseRedirect(reverse('simplesite:login_ok', kwargs={'username': username}))
        else:
            messages.error(request, '登录失败,请检查用户名和密码;如果尚未注册,请先注册!')

    form = UserLoginForm
    context = {'form': form}
    return render(request, 'login.html', context)

  

  

在登录函数里,通过authenticate,直接去匹配一个用户-密码对象,如果为not None,表示当前用户-密码能对应一个对象,即存在!

之后,还必须调用login()函数,将request和login_user传入,最终才实现登录!如果你在之前曾经在/admin里登录了其他帐号,此时会被踢掉。

否则,通过messages.error()增加一个提示反馈,然后仍然返回到当前页面。

注意:messages不需要放入上下文,但是需要在模板里对messages进行处理:

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body>
    {% for message in messages %}
        <p>{{message}}</p>
    {% endfor %}
    <form action="{% url 'account:login' %}" method="post">
        {% csrf_token %}
        {{form.as_p}}
        <span><input type="submit" value="login" /><a href="{% url 'account:register' %}">register</a></span>
    </form>
</body>
</html>

 

具体的message,通过for——in——取出来。

 

在注册部分:

def user_register(request):
    form = UserRegForm
    context = {'form': form}
    if request.method != 'POST':
        return render(request, 'reg.html', context)
    else:
        form = UserRegForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            email = form.cleaned_data['email']
            confirm_password = form.cleaned_data['confirm_password']
            im_qq = form.cleaned_data['im_qq']
            if password == confirm_password:
                already_user = User.objects.filter(username=username)
                if already_user:
                    messages.error(request, '该用户已存在!')
                    return render(request, 'reg.html', context)
                else:
                    new_user = User.objects.create_user(username=username, password=password, email=email)
                    new_exuser = ExUser(user=new_user)
                    new_exuser.confirm_password = confirm_password
                    new_exuser.im_qq = im_qq
                    new_exuser.save()
                    # 注册完成后,同时进行登录
                    login(request, new_user)
                    return HttpResponseRedirect(reverse('simplesite:login_ok'))
            else:
                messages.error(request, '两次密码输入不一致,请重新填写注册信息!')
                return render(request, 'reg.html', context)
        else:
            messages.error(request, '发生异常错误,未收到注册信息,请尝试重新填写或刷新页面!')
            return render(request, 'reg.html', context)

  

判断比较多,非常复杂,可能应该有更好的方式!

非POST传值的部分就不用看了,主要看第一个else之后的内容:

  1. 首先用一个form保存post传来的值,如果获取不到,反馈第一个提示:messages.error(request, '发生异常错误,未收到注册信息,请尝试重新填写或刷新页面!')
  2. 接着检查两次密码是否输入一致,否则会提示密码输入错误:messages.error(request, '两次密码输入不一致,请重新填写注册信息!')
  3. 如果密码输入一致,此时这个帐号的信息基本满足注册,但是还需要判断当前用户名是否已经存在,如果存在则仍然不能进行注册:messages.error(request, '该用户已存在!')
  4. 以上所有判断全部检查完毕后,方可进行相关的保存动作,完成注册,并且用这个刚刚注册的帐号去登录。

【问题】

  • 有很多重复的return render代码,这里应该可以优化;
  • 在界面中弹出对话框可能比较好。

 

--------------------------------------------------------------

代码的第一部分优化

--------------------------------------------------------------

 

'''
def login(request):
    form = UserLoginForm
    context = {'form': form}
    if request.method != 'POST':
        return render(request, 'login.html', context)
    else:
        username = request.POST['username']
        password = request.POST['password']
        login_user = authenticate(request, username=username, password=password)
        if login_user is not None:
            return HttpResponseRedirect(reverse('simplesite:login_ok'))
        else:
            messages.error(request, '登录失败,请检查用户名和密码;如果尚未注册,请先注册!')
            return render(request, 'login.html', context)
'''


def login(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        login_user = authenticate(request, username=username, password=password)
        if login_user is not None:
            return HttpResponseRedirect(reverse('simplesite:login_ok'))
        else:
            messages.error(request, '登录失败,请检查用户名和密码;如果尚未注册,请先注册!')

    form = UserLoginForm
    context = {'form': form}
    return render(request, 'login.html', context)

  

这样修改之后,两个分支最终都通过最后一行的return render(request, 'login.html', context)来实现页面,其中一个分支运行到这里时还会添加messages内容。

理论上,第二个if完成后,仍然会持续后续内容,但是这里的if比较特殊,他通过url的跳转,会执行其他的views函数。