【愚公系列】2022年01月 Django商城项目12-登录界面-登录和退出功能实现
【摘要】 一、登录功能实现 1.使用django自带的用户登录模型配置# 允许自定义用户模型类AUTH_USER_MODEL = 'users.User'# 修改默认的认证后端AUTHENTICATION_BACKENDS = [ # 'django.contrib.auth.backends.ModelBackend' 'app.users.utils.UsernameMobileMo...
一、登录功能实现
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数据进行判断用户是否登录,进行相应展示。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)