前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【愚公系列】2022年01月 Django商城项目12-登录界面-登录和退出功能实现

【愚公系列】2022年01月 Django商城项目12-登录界面-登录和退出功能实现

作者头像
愚公搬代码
发布2022-01-17 21:08:51
4090
发布2022-01-17 21:08:51
举报
文章被收录于专栏:历史专栏历史专栏

文章目录

一、登录功能实现

1.使用django自带的用户登录模型配置

# 允许自定义用户模型类
AUTH_USER_MODEL = 'users.User'

# 修改默认的认证后端
AUTHENTICATION_BACKENDS = [
    # 'django.contrib.auth.backends.ModelBackend'
    'app.users.utils.UsernameMobileModelBackend',
]

# LOGIN_URL 的默认值是 : accounts/login/
# 我们只需要修改这个配置信息就可以,修改成 符合我们的路由就可以
LOGIN_URL = '/login/'

2.UsernameMobileModelBackend校验函数源码

import re

from django.contrib.auth.backends import ModelBackend

from app.users.models import User

from django.http import JsonResponse
"""
封装/抽取的思想

    为什么要封装/抽取?
    1.降低代码的耦合度      (高内聚,低耦合)
    2.提高代码的重用性      (很多地方都用到了重复的代码)

    抽取/封装的步骤
    1.定义一个函数(方法),把要抽取的代码复制过来
    2.哪里有问题改哪里,没有的变量以参数的形式定义
    3.验证抽取方法

    什么时候进行抽取/封装
    1. 某几行代码实现了一个小功能我们就可以抽取/封装
    2. 我们的代码只要第二次重复使用就抽取/封装
"""

def get_user_by_username(username):
    try:
        if re.match(r'1[3-9]\d{9}', username):
            # username 是手机号
            user = User.objects.get(mobile=username)

        else:
            # username 是用户名
            user = User.objects.get(username=username)
    except User.DoesNotExist:
        return None

    return user


class UsernameMobileModelBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        # 1. 先查询用户
        # username 有可能是 手机号 也有可能是用户名
        # 通过对username进行正则来区分
        user = get_user_by_username(username)
        # 2. 判断用户的密码是否正确
        if user is not None and user.check_password(password):
            return user

替换上面默认认证后就可以使用手机号或者账号进行登录了。

3.登录的业务逻辑实现

class LoginView(View):

    def get(self,request):

        return render(request,'login.html')

    def post(self,request):
        # 1.后端需要接收数据 (username,password)
        username=request.POST.get('username')
        passwrod=request.POST.get('password')
        remembered=request.POST.get('remembered')
        # 2.判断参数是否齐全
        if not all([username,passwrod]):
            return http.HttpResponseBadRequest('缺少必须的参数')
        # 3.判断用户名是否符合规则
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$',username):
            return http.HttpResponseBadRequest('用户名不符合规则')
        # 4.判断密码是否符合规则
        if not re.match(r'',passwrod):
            return http.HttpResponseBadRequest('密码不符合规则')
        # 5.验证用户名和密码
        # 验证有2种方式
        # ① 使用django的认证后端
        # ② 我们可以自己查询数据库( 根据用户名/手机号查询对应的user用户,再比对密码)

        from django.contrib.auth import authenticate
        # 默认的认证后端是调用了 from django.contrib.auth.backends import ModelBackend
        # ModelBackend 中的认证方法
        # def authenticate(self, request, username=None, password=None, **kwargs):

        # 如果用户名和密码正确,则返回user
        # 否则返回None
        user = authenticate(username=username,password=passwrod)

        # is_authenticated 是否是认证用户
        # 登陆用户返回 true
        # 未登陆用户返回 false
        # request.user.is_authenticated

        if user is not None:
            # 6.如果验证成功则登陆,状态保持
            #登陆成功
            login(request,user)


            if remembered == 'on':
                #记住登陆
                # request.session.set_expiry(seconds)
                request.session.set_expiry(30*24*3600)
            else:
                # 不记住
                request.session.set_expiry(0)


            # 如果有next参数,则跳转到指定页面
            # 如果没有next参数,则跳转到首页
            next = request.GET.get('next')
            if next:
                response = redirect(next)
            else:

                response = redirect(reverse('contents:index'))

            #设置cookie
            # response.set_cookie(key,value,max_age)
            response.set_cookie('username',user.username,max_age=14*24*3600)

            ## 合并cookie数据到redis中
            #merge_cookie_to_redis(request,user,response)

            return response
        else:
            #登陆失败
            # 7.如果验证不成功则提示 用户名或密码错误
            return render(request,'login.html',context={'account_errmsg':'用户名或密码错误'})

4.用户名展示

django模板会自动嵌入request对象,可以在模板中直接使用cookie

具体用户名展示的视图写法如下:

<div class="header_con">
	<div class="header">
		<div class="welcome fl">欢迎来到小徐商城!</div>
		<div class="fr">
			<div v-if="username" class="login_btn fl">
				欢迎您:<em>[[ username ]]</em>
				<span>|</span>
				{#                    url 本质是 reverse#}
				<a href="{{ url('users:logout') }}">退出</a>
			</div>
			<div v-else=v-else class="login_btn fl">
				<a href="users/login">登录</a>
				<span>|</span>
				<a href="users/register">注册</a>
			</div>
			<div class="user_link fl">
				<span>|</span>
				<a href="center">用户中心</a>
				<span>|</span>
				<a href="../static/cart.html">我的购物车</a>
				<span>|</span>
				<a href="../static/user_center_order.html">我的订单</a>
			</div>
		</div>
	</div>
</div>

vue中

var vm = new Vue({
    el: '#app',
    // 修改Vue变量的读取语法,避免和django模板语法冲突
    delimiters: ['[[', ']]'],
    data: {
        host,
        f1_tab: 1, // 1F 标签页控制
        f2_tab: 1, // 2F 标签页控制
        f3_tab: 1, // 3F 标签页控制
        cart_total_count: 0, // 购物车总数量
        carts: [], // 购物车数据,
        username:'',
    },
    mounted(){
        this.username = this.getCookie('username');
    },
    methods: {
    	getCookie(name) {
		    var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
		    return r ? r[1] : undefined;
		}
    }
});

5.实际效果

在这里插入图片描述
在这里插入图片描述

二、退出功能实现

1.退出的业务逻辑实现

class LogoutView(View):

    def get(self,request):

        # request.session.flush()

        # 系统其他也给我们提供了退出的方法

        logout(request)

        # 退出之后,我们要跳转到指定页面
        # 还跳转到首页
        # 需要额外删除cookie中的name,因为我们首页的用户信息展示是通过username来判断

        response = redirect(reverse('contents:index'))

        response.delete_cookie('username')

        return response

总结

登录和退出功能取决与是否有cookie,在页面加载时vue会自动获取cookie数据进行判断用户是否登录,进行相应展示。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-01-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、登录功能实现
    • 1.使用django自带的用户登录模型配置
      • 2.UsernameMobileModelBackend校验函数源码
        • 3.登录的业务逻辑实现
          • 4.用户名展示
            • 5.实际效果
            • 二、退出功能实现
              • 1.退出的业务逻辑实现
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档