
教程全知识点简介:1.用户管理系统涵盖收货地址(省市区三级联动、新增地址、设置默认地址、修改地址标题)、修改密码、用户中心功能。2. 商品管理包括商品数据库表设计、SPU和SKU概念、首页广告数据库表分析、商品数据准备、Django文件存储类、商品列表页(面包屑导航、分页排序)。3. 搜索功能涵盖商品搜索、Haystack扩展索引建立、全文检索测试、搜索结果渲染。4. 商品详情系统包括详情页分析准备、SKU详情信息渲染、商品访问量统计、浏览记录存储方案。5. 购物车管理涉及添加购物车、展示商品页面购物车功能。6. 订单系统包括订单数据库表创建、订单基本信息保存、事务保存订单数据、乐观锁并发下单、订单提交。7. 支付系统涵盖支付宝介绍(沙箱环境、开发文档、网站支付流程、RSA2公私钥配置)、支付宝系统对接、订单支付功能、支付结果保存。8. 项目部署包括容器化方案Docker、页面静态化、数据库主从配置(从机端口号、二进制日志文件、主从连接)。9. 项目工程配置涵盖工程日志配置、前端静态文件配置、工程创建配置、项目准备。10. 用户认证系统包括用户注册(注册页面展示、业务实现、前端逻辑、参数验证、数据保存)、状态保持、图形验证码、短信验证码(容联云通讯平台、pipeline操作Redis、RabbitMQ消息队列)、账号登录、QQ登录(OAuth2.0认证、openid处理、用户绑定)、用户基本信息管理、邮箱添加。

账号登录
用户名登录
1. 用户名登录逻辑分析

2. 用户名登录接口设计
1.请求方式
| 选项 | 方案 |
|---|---|
| 请求方法 | POST |
| 请求地址 | /login/ |
2.请求参数:表单
| 参数名 | 类型 | 是否必传 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名 |
| password | string | 是 | 密码 |
| remembered | string | 是 | 是否记住用户 |
3.响应结果:HTML
| 字段 | 说明 |
|---|---|
| 登录失败 | 响应错误提示 |
| 登录成功 | 重定向到首页 |
3. 用户名登录接口定义
class LoginView(View):
"""用户名登录"""
def get(self, request):
"""
提供登录界面
:param request: 请求对象
:return: 登录界面
"""
pass
def post(self, request):
"""
实现登录逻辑
:param request: 请求对象
:return: 登录结果
"""
pass
4. 用户名登录后端逻辑
class LoginView(View):
"""用户名登录"""
def get(self, request):
"""
提供登录界面
:param request: 请求对象
:return: 登录界面
"""
return render(request, 'login.html')
def post(self, request):
"""
实现登录逻辑
:param request: 请求对象
:return: 登录结果
"""
# 接受参数
username = request.POST.get('username')
password = request.POST.get('password')
remembered = request.POST.get('remembered')
# 校验参数
# 判断参数是否齐全
if not all([username, password]):
return http.HttpResponseForbidden('缺少必传参数')
# 判断用户名是否是5-20个字符
if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
return http.HttpResponseForbidden('请输入正确的用户名或手机号')
# 判断密码是否是8-20个数字
if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
return http.HttpResponseForbidden('密码最少8位,最长20位')
# 认证登录用户
user = authenticate(username=username, password=password)
if user is None:
return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'})
# 实现状态保持
login(request, user)
# 设置状态保持的周期
if remembered != 'on':
# 没有记住用户:浏览器会话结束就过期
request.session.set_expiry(0)
else:
# 记住用户:None表示两周后过期
request.session.set_expiry(None)
# 响应登录结果
return redirect(reverse('contents:index'))
5. 知识要点
-
登录的核心思想:认证和状态保持
- 通过用户的认证,确定该登录用户是美多商场的注册用户。
- 通过状态保持缓存用户的唯一标识信息,用于后续是否登录的判断。
多账号登录
-
Django自带的用户认证后端默认是使用用户名实现用户认证的。
-
用户认证后端位置:django.contrib.auth.backends.ModelBackend。
-
如果想实现用户名和手机号都可以认证用户,就需要自定义用户认证后端。
-
自定义用户认证后端步骤
-
在users应用中新建utils.py文件
-
新建类,继承自ModelBackend
-
重写认证authenticate()方法
-
分别使用用户名和手机号查询用户
-
返回查询到的用户实例
-
1. 自定义用户认证后端
users.utils.py
from django.contrib.auth.backends import ModelBackend
import re
from .models import User
def get_user_by_account(account):
"""
根据account查询用户
:param account: 用户名或者手机号
:return: user
"""
try:
if re.match('^1[3-9]\d{9}$', account):
# 手机号登录
user = User.objects.get(mobile=account)
else:
# 用户名登录
user = User.objects.get(username=account)
except User.DoesNotExist:
return None
else:
return user
class UsernameMobileAuthBackend(ModelBackend):
"""自定义用户认证后端"""
def authenticate(self, request, username=None, password=None, **kwargs):
"""
重写认证方法,实现多账号登录
:param request: 请求对象
:param username: 用户名
:param password: 密码
:param kwargs: 其他参数
:return: user
"""
# 根据传入的username获取user对象。username可以是手机号也可以是账号
user = get_user_by_account(username)
# 校验user是否存在并校验密码是否正确
if user and user.check_password(password):
return user
2. 配置自定义用户认证后端
1.Django自带认证后端源码

2.配置自定义用户认证后端
# 指定自定义的用户认证后端
AUTHENTICATION_BACKENDS = ['users.utils.UsernameMobileAuthBackend']
3. 测试自定义用户认证后端

4. 知识要点
-
Django自带的用户认证系统只会使用用户名去认证一个用户。
- 所以我们为了实现多账号登录,就可以自定义认证后端,采用其他的唯一信息去认证一个用户。
首页用户名展示

1. 首页用户名展示方案
方案一
- 模板中 request 变量直接渲染用户名
- 缺点:不方便做首页静态化
{% if user.is_authenticated %}
<div class="login_btn fl">
欢迎您:<em>{{ user.username }}</em>
<span>|</span>
<a href="#">退出</a>
</div>
{% else %}
<div class="login_btn fl">
<a href="login.html">登录</a>
<span>|</span>
<a href="register.html">注册</a>
</div>
{% endif %}
方案二
- 发送ajax请求获取用户信息
- 缺点:需要发送网络请求
<div class="login_btn fl">
{# ajax渲染 #}
</div>
方案三
- Vue读取cookie渲染用户信息
<div v-if="username" class="login_btn fl">
欢迎您:<em>[[ username ]]</em>
<span>|</span>
<a href="#">退出</a>
</div>
<div v-else class="login_btn fl">
<a href="login.html">登录</a>
<span>|</span>
<a href="register.html">注册</a>
</div>
结论:
- 对比此三个方案,我们在本项目中选择 方案三
实现步骤:
- 注