django项目--登陆登出功能

一、功能需求分析

1、登陆功能分析

1.1、流程

1.2、功能

  • 登陆页面
  • 登陆功能
  • 登出功能

二、登陆页面

1、接口设计

1.1、接口说明

类目 说明
请求方式 GET
url /user/login/
参数 无参数

1.2、返回结果

登陆界面

三、登陆功能

1、业务流程

1.1、参数校验

  • 账户校验
  • 密码校验
  • 账户密码联合校验

1.2、登陆逻辑

1. 在session中保存状态
2. 根据记住我选项,进行有效期的设置,(session_id)

2、接口设计

2.1、接口说明

类目 说明
请求方式 POST
url /user/login/
参数 表单

2.2、参数说明

参数名 类型 是否必须 描述
account 字符串 用户输入的账号,手机号码或用户名
password 字符串 用户输入的密码
remember 字符串 用户是否勾选免登陆

2.3、返回结果

{
    errno:'0',
    errmsg:'ok',
}

登陆界面

2、后台代码

2.1、视图

class LoginView(View):
    """
    登陆视图
    url:/user/login/
    """
    def get(self,request):
        return render(request,'user/login.html')
    def post(self,request):
        #1、先校验
        form = LoginForm(request.POST,request=request)
        if form.is_valid():
            return json_response(errmsg='恭喜登陆成功!')
        else:
            # 将表单报错信息进行拼接
            err_msg_list = []
            for item in form.errors.values():
                err_msg_list.append(item[0])

            err_msg_str = '/'.join(err_msg_list)
            return json_response(errno=Code.PARAMERR, errmsg=err_msg_str)

2.2、form表单

class LoginForm(forms.Form):
    """
    登陆校验表单
    """
    account = forms.CharField(error_messages={'required':'账户不能为空'})

    password = forms.CharField(label='密码', max_length=20, min_length=6, error_messages={
        'max_length': '密码长度小于20!',
        'min_length': '密码长度大于6!',
        'required': '密码不能为空!',
    })

    remember = forms.BooleanField(required=False)

    def __init__(self,*arge,**kwargs):
        self.request = kwargs.pop('request', None)
        super().__init__(*arge,*kwargs)

    def clean_account(self):
        """
        校验用户名
        :return:
        """
        account = self.cleaned_data.get('account')
        if not re.match(r'^1[3-9]\d{9}$',account) and (len(account) >20 or len(account) < 5):
            raise forms.ValidationError('用户账号格式不正确,请重新输入!')
        return account

    def clean(self):
        """
        校验用户名密码,并实现登陆逻辑
        :return:
        """
        clean_data = super().clean()
        account = clean_data.get('account')
        password = clean_data.get('password')
        remember = clean_data.get('remember')

        #登陆逻辑
        #判断是否用户名密码是否匹配
        #先找到用户,在判断校验这个密码是否匹配
        #select * from tb_user where mobile=account or username=account
        user_qureyset = User.objects.filter(Q(mobile=account)|Q(username=account))
        if user_qureyset:
            user = user_qureyset.first()
            if user.check_password(password):
                #是否免登陆,remember
                if remember:
                    #免登陆14天
                    self.request.session.set_expiry(14*24*60*60)
                else:
                    #关闭浏览器即清除登陆状态
                    self.request.session.set_expiry(0)
                #登陆
                login(self.request,user)
            else:
                raise forms.ValidationError('账户密码错误')
        else:
            raise forms.ValidationError('用户账户不存在,请重新输入!')

        return clean_data

2.3、js

$(function () {
    let $loginBtn = $('.login-btn');    // 获取登录按钮元素

    $loginBtn.click(function (e) {
        e.preventDefault(); // 阻止默认提交
        // 1.校验账户
        let sAccount = $('input[name="account"]').val();
        if (sAccount === ''){
            message.showError('用户账户不能为空');
            return
        }
        if(!(/^\w{5,20}$/).test(sAccount) && !(/^1[3-9]\d{9}$/).test(sAccount)){
            message.showError('用户账户格式不正确,请求重新输入');
            return
        }
        // 2.校验用户输入密码
        let sPassword = $('input[name="password"]').val();
        if(sPassword === ''){
            message.showError('用户密码不能为空');
            return
        }
        // 3.获取用户是否勾选'记住我',勾选为true,否则为false
        let bRemember = $('input[name="remember"]').is(':checked');
        // 4.发送ajax
        $.ajax({
            url: '/user/login/',
            data: {
                account: sAccount,
                password: sPassword,
                remember: bRemember
            },
            type: 'POST',
            dataType: 'json',
            success: function (res) {
                if(res.errno === '0'){
                    message.showSuccess('恭喜, 登录成功!');
                    setTimeout(function () {
                        //注册成功之后重定向到打开登录页面之前的页面
                        if(!document.referrer || document.referrer.includes('/user/login/') || document.referrer.includes('/user/register/')){
                            window.location.href = '/'
                        }else {
                            window.location.href = document.referrer
                        }
                    }, 1000)
                }else{
                    message.showError(res.errmsg)
                }
            },
            error: function (xhr, msg) {
                message.showError('服务器超时,请重试')

            }
        });
    });
});

2.4、url

path('login/', views.LoginView.as_view(), name='login'),

四、登出功能

1、接口设计

1.1、接口说明

类目 说明
请求方式 GET
url /user/logout/
参数 无参数
1.2、返回结果

登出

2、后台代码

2.1 、视图

from django.contrib.auth import logout


class LogoutView(View):
    def get(self,request):
        logout(request)

        return redirect(reverse('user:login'))

2.2、url

path('logout/', views.LogoutView.as_view(), name='logout'),

你可能感兴趣的:(django项目--登陆登出功能)