前后端不分离 用户
# 02-注册页面
#### web开发流程:
* 1.前端发请求 --后台
* 2.后台
* 正则校验过 路由url--接收请求:
* --解析请求----解析参数
* 业务逻辑处理 crud
* 3.返回给前端数据
* render(request,'index.html',context={})
* JsonResponse([],safe=False)
####请求方式:request.method
* GET -------查询
* POST------增加
* PUT --------修改
* Delete---------删除
#### 传参的四种方式:4个
* ?a=12&b=20----------request.GET==>queryDict.get() getlist()
* /a/b/ ----------------- 直接解析---def get(self,request,a,b)
* 请求体:
* 非表单 ---------- json-----request.body===>bytes==decode()=== json.loads(json_str)
* 表单 ----------------request.POST
* 请求头 ---------------request.META
#### vue 基本操作:
* 1.隐藏和显示 v-show
* 2.--v-model: input select textarea
* 3.操作属性 v-bind 简写 :
* 4. 操作事件 v-on 简写 @
* 5. 大量的重复标签: v-for
* 6. 条件判断 v-if v-else-if
* 7.操作数据 {{ }}===jinja2 {{ }}
* 8. vue的生命周期:mounted 对象加载完毕
#### django数据库查询: ORM
* User模型类
* 增
* Save()
* create() ------User.objects.create()
* 删
* Delete()
* User.objects.filter(id=1).delete()
* 改
* Save()
* Update()---User.objects.filter(id=1).update()
* 查
* get() all() filter()
* 关联查询
* 1:n -----1.n纯小写_set(related_name).all() ---------1.objects.filter(n纯小写___n的属性=值)
* n(外键):1-----n.外键属性---------------------------------------------n.objects.filter(外键属性__运算符=值)
* 外键属性 外键_id hbook hbook_id
### 作业 注册容联云账号,熟悉页面和开发文档--10分钟 https://www.yuntongxun.com/
* 1.千万记得 每天第一件是 测试代码运行是否成功!
* 2.根据提交的日志 看一下昨天的进度
* 3.替换文件 素材---替换文件
## 1.注册功能 POST
```python
# 1.解析参数--request.POST
# 2.判空
# 3.判正则
# 4.注册---->增加 create() save()
# 5.重定向到首页
pass
# 接口文档
# url: register
# method:POST
# 参数:form传参
# 响应:成功---跳转首页
# 失败--- 提示
# 1.用户名 ---判空--判正则---是否重复
# 2.密码 ---判空--判正则
# 3.确认密码 == 是否一致
# 4.手机号 ---判空--判正则---是否重复
# 5.协议 ---必须勾选
# 图形验证码 ---判空-
# 短信验证码 ---判空-
```
创建用户模块应用 在apps
包下创建应用users
展示用户注册页面
注册用户模块应用 准备用户注册模板文件 请求方式和路由
定义用户注册视图 1.总路由 2.子路由
## 2.用户的模型类 https://yiyibooks.cn/xx/Django_1.11.6/topics/auth/customizing.html
```python
用户模型类自定义
新知识点: ---使用django的User模型类: 原因: 加解密密码--权限认证--用户管理
----自定义User模型类: 不满足 mobile 手机号
# 1.models.py : 自定义User模型类: 导包 继承AbstractUser 添加新属性 mobile字段 粘贴
# 2.dev.py -- 修改 djangoUser模型类 配置:AUTH_USER_MODEL = 'users.User'
# 3.数据迁移 python manage.py makemigrations
python manage.py migrate
```
## 3. 注册用户 功能
* 1. 开开发文档-- 使用user对象
* `from apps.ausers.models import User
User.objects.create_user(username=username,password=password,mobile=mobile)
`
## 2. 创建了首页contents 应用--注册app--总路由--子路由---类视图函数---render(request,'index.html')
* 1.替换 index.html index.js
* 2.注册子应用contents--注册app.--zong--zi --类视图---render
##3.保持登录状态 --session--cookie
* 1.session 1.设置request.session['k'] =v 2. request.session['k']校验 保持登录状态 === 原生代码
* 2.django User保持登录状态login(request,user)
* 127.0.0.1:6379 connection refused --- redis没开启服务
* duplicate zhangsan -----用户名重复注册
# 1. 注册页面显示
# 1.路由
# 2.类视图 get
# 3.render(request,'register.html')
# 1.解析参数--request.POST
# 判断空 all()
# 1.用户名 ---判空--判正则---是否重复
# 2.密码 ---判空--判正则
# 3.确认密码 == 是否一致
# 4.手机号 ---判空--判正则---是否重复
# 5.协议 ---必须勾选
# 短信验证码 ---判空-
# 1.获取用户 给的 参数 sms_code
# 2.链接redis 数据库 3号库
# 3.取出redis的短信
# 4. 用户短息 和 后台redis短信校验
# 4.注册---->增加 create() save()
# 保持登录状态 === 原生代码: request.session['user_id']=user.id
# django认证系统:login(request,user)
# 5.重定向到首页
## 4.判断用户名是否重复
* 1.接收用户名 username
* 2.校验判空 和 正则
* 3.逻辑数据库查询 User.objects.filter(username=username).count()
* 4.返回给前端
## 5.判断手机号是否重
- 1.接收用户名 username
- 2.校验判空 和 正则
- 3.逻辑数据库查询 User.objects.filter(mobile=mobile).count() 查询数据库 user用户 --统计个数
- 4.返回给前端
## 6.图片验证码
* 1. 前端发请求-->key---UUID 唯一码
2. 接收请求 UUID 参数, 正则校验
3. 生成图片验证码( 随机产生的 )--第三方
4. 使用redis存储 随机码(UUID:code)--django_redis
5. 返回前端 图片验证码--二进制流 content_type="image/png"
获取图片验证码
# 1.接收参数(前端发请求-->key---UUID 唯一码)
# 2.正则校验(接收请求 UUID 参数, 正则校验)
# 3.生成图片验证码 (使用django-redis存储 随机码(UUID:code))
# 4.保存图片验证码---redis--'verify_image_code' 设置过期时间setex (# constants.IMAGE_CODE_REDIS_EXPIRES 代码易扩展)
# 5.返回前端 图片--bytes ----MIME ----文件格式 'image/png' )(返回前端 图片验证码--二进制流)
## 7.短信验证码
#### 1.容联云的介绍
* 1.注册
* 2.创建应用
* 3.开发文档
* 4.下载 SDK 包
#### 2.发短信流程
* 1.接收参数 解析参数
* 2.校验图形验证码
* 3.生成随机6位码
* 4.发送短信CCP
* 5.使用redis存储 6位码
* 6.返回响应对象
03-验证码
## 1.短信验证码
* 1.接收 2个 mobile; 图片验证码img_code
* 2.验证码 img_code和redis存储的验证码 是否一致 (1.redis取出来(4步) 2.判断是否相等 3.redis img_code 删除) **千万注意 redis取出来类型 是 Bytes.decode()**
* 3.生成随机 6位 短信验证码内容 random.randit()
* 4.存储 随机6位 redis里面(3步 )
* 5.发短信---第三方容联云--
* 6.返回响应对象
## 2.注册验证短信验证码
* ```python
2. 补充了 注册功能-- 短信校验
1. 接收 用户 输入的 短信---注意:msg_code
2. 链接redis
3. 从redis 取短信
4. 校验
```
## 3.后台避免频繁发送短信
* 1.标记--开关(按钮点击, 不能点击)
* 2. 60秒倒计时:---redis.setex(k,60,1)
3. 获取redis里面的标识
4. 标识没有---重新发短信--重新倒计时
5. 标识有---直接return
## 4.redis管道操作
* 1.作用: 减少 redis客户端和后台的交互,提高操作效率
* 2. pipeline = client.pipeline()
3. pipeline.setex()
4. pipeline.exectue()
# 5.生产消费者模式
#### 1. 生产者 --- 消息队列----消费者
* 生产者productor----负责产生任务
* 消息队列broker---先进先去 --- 存储任务的仓库--redis或者rabbitmysql
* 消费者worker---- 执行任务
*
#### 2.celery
* 将 生产者, 消息队列,消费者 三者 统一管理调度, 减少重复代码,和 调用流程的工具
#### 3.celery的操作
* 1. pip install -U Celery
2. 在项目目录下---celery_tasks 包
3. celery_tasks 包---main.py
4. --main.py: 1.导包celery 2.os环境配置--django项目环境 3.实例化对象
5. 消息队列broker---config.py -``---main.py---加载配置文件
6. 生产者:--celery_tasks 包-->sms包--tasks.py(名字不能改)
7. -tasks.py(名字不能改)---1. 把以前发短信的代码粘贴过来 --写个函数 2.@app.task
8. main.py---注册任务
9. 消费者: ---进终端--启动服务--- 粘贴指令 `celery -A celery_tasks.main worker -l info`
10. 注册功能里面 --触发 异步任务 delay
短信验证码
# 1.解析参数 front_img_code uuid
# 2.校验
3.校验图片验证码--redis
# 3.1 链接redis2号数据库
# 3.2 从redis取出 存储的图片验证码
# 千万注意: redis取出来的值 ---bytes=-decode()
# 4. 生成随机 6位码数 import random
# 5. 保存 6位码数---redis
# 5.1 链接redis3号数据库 使用 容联云 发送短信
# 1.获取 redis里面的标识
# 2.判断 如果倒计时的标识在-- 不再发送
# 创建管道(存储短信)
# 3.重新倒计时 60秒
# 5.2 去redis 存储的 短信验证码
# 执行管道
# 异步发送短信 使用 celery
# 6. 返回响应对象
# 6. 用户登录
##### 1.登录页面显示 render
##### 2. 登录功能
* 1.接收参数 : username password 记住登录remembered
* 2.校验
* 3. 判断用户名和密码 是否正确(
# orm --传统---User.objects.get(username=username,password=password)
# django认证系统 authenticate(username=username,password=password)
)
4. 保持登录状态 login()
# 记住 None 默认 2 周
# 不记住 -- 会话结束就失效
# next 获取
5. 跳转到首页 redirect(reverse('contents:index'))
##### 3. 首页显示用户名
* 1.login.html ---- > index.html
* 2.sessionid--user_id--->ajax---user
* 3.request.user ---
* 4. Login--存储到response.set_cookie---前端index.js--从cookie读取
##### 3. 首页显示用户名
* 1.login.html ---- > index.html
* 2.sessionid--user_id--->ajax---user
* 3.request.user ---
* 4. Login--存储到response.set_cookie---前端index.js--从cookie读取
#### 4.多账号登录: authenticate() 写在utils里面
* 1.扩展自己的mobile识别登录功能 自定义 ; django.contrib.auth.backends.ModelBackend
根据account查询用户,判断 用户名 和 手机号的 多账号
* 1. 导包 from django.contrib.auth.backends import ModelBacken
2. 继承
3. 重写父类函数 authenticate
# 根据传入的username获取user对象。username可以是手机号也可以是账号
# 校验user是否存在并校验密码是否正确
4. 去配置文件 dev.py 修改配置 AUTHENTICATION_BACKENDS = ['apps.users.utils.UsernameMobileAuthBackend']
#### 5. 退出--logout(request)
#### 6. 判断是否登录
* 1. user = User.objects.get(username=username) if user:
2. Is_authenticate():
3. 装饰器 login_required
4. 扩展类 LoginRequiredMixin
# 1.退出本质--清除session request.session.clear()
# 2. logout() logout(request)
# 重定向首页
# 清空cookie response.delete_cookie('username') 退出登录时清除cookie中的username