【Django开发】0到1开发美多shop项目:图形和短信验证码。全md文档笔记(附代码,已分享)

本系列文章md笔记(已分享)主要讨论django商城项目相关知识。项目利用Django框架开发一套前后端不分离的商城项目(4.0版本)含代码和文档。功能包括前后端不分离,方便SEO。采用Django + Jinja2模板引擎 + Vue.js实现前后端逻辑,Nginx服务器(反向代理)Nginx服务器(静态首页、商品详情页、uwsgi服务器(美多商场业务场景),后端服务:MySQL、Redis、Celery、RabbitMQ、Docker、FastDFS、Elasticsearch、Crontab,外部接口:容联云、QQ互联、支付宝。

全套笔记和代码自取移步gitee仓库: gitee仓库获取完整文档和代码

感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~


共 11 章,132 子模块

图形验证码

图形验证码接口设计和定义

1. 图形验证码接口设计

1.请求方式

|选项|方案| |---|---| |请求方法|GET| |请求地址|image_codes/(?P[\w-]+)/|

2.请求参数:路径参数

|参数名|类型|是否必传|说明| |---|---|---|---| |uuid|string|是|唯一编号|

3.响应结果:image/jpg

2. 图形验证码接口定义

1.图形验证码视图

```python class ImageCodeView(View): """图形验证码"""

def get(self, request, uuid):""":param request: 请求对象:param uuid: 唯一标识图形验证码所属于的用户:return: image/jpg"""pass

```

2.总路由

```python

verifications

url(r'^', include('verifications.urls')), ```

3.子路由

```python

图形验证码

url(r'^image_codes/(?P [\w-]+)/$', views.ImageCodeView.as_view()), ```

图形验证码后端逻辑

1. 准备captcha扩展包

提示:captcha扩展包用于后端生成图形验证码

可能出现的错误

  • 报错原因:环境中没有Python处理图片的库:PIL

解决办法

  • 安装Python处理图片的库:pip install Pillow

2. 准备Redis数据库

准备Redis的2号库存储验证码数据

python "verify_code": { # 验证码 "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/2", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } },

3. 图形验证码后端逻辑实现

```python class ImageCodeView(View): """图形验证码"""

def get(self, request, uuid):""":param request: 请求对象:param uuid: 唯一标识图形验证码所属于的用户:return: image/jpg"""# 生成图片验证码text, image = captcha.generate_captcha()# 保存图片验证码redis_conn = get_redis_connection('verify_code')redis_conn.setex('img_%s' % uuid, constants.IMAGE_CODE_REDIS_EXPIRES, text)# 响应图片验证码return http.HttpResponse(image, content_type='image/jpg')

```

图形验证码前端逻辑

1. Vue实现图形验证码展示

1.register.js

js mounted(){ // 生成图形验证码 this.generate_image_code(); }, methods: { // 生成图形验证码 generate_image_code(){ // 生成UUID。generateUUID() : 封装在common.js文件中,需要提前引入 this.uuid = generateUUID(); // 拼接图形验证码请求地址 this.image_code_url = "/image_codes/" + this.uuid + "/"; }, ...... }

2.register.html

```html

  • 图形验证码 请填写图形验证码
  • ```

    3.图形验证码展示和存储效果

    2. Vue实现图形验证码校验

    1.register.html

    ```html

  • 图形验证码 [[ error_image_code_message ]]
  • ```

    2.register.js

    js check_image_code(){ if(!this.image_code) { this.error_image_code_message = '请填写图片验证码'; this.error_image_code = true; } else { this.error_image_code = false; } },

    3.图形验证码校验效果

    短信验证码

    短信验证码逻辑分析

    知识要点

    1. 保存短信验证码是为注册做准备的。
    2. 为了避免用户使用图形验证码恶意测试,后端提取了图形验证码后,立即删除图形验证码。
    3. Django不具备发送短信的功能,所以我们借助第三方的容联云通讯短信平台来帮助我们发送短信验证码。

    容联云通讯短信平台

    1. 容联云通讯短信平台介绍

    1.容联云官网

    • 容联云通讯网址:https://www.yuntongxun.com/
    • 注册并登陆

    2.容联云管理控制台

    3.容联云创建应用

    4.应用申请上线,并进行资质认证

    5.完成资质认证,应用成功上线

    6.添加测试号码

    7.短信模板

    2. 容联云通讯短信SDK测试

    1.模板短信SDK下载

    • https://www.yuntongxun.com/doc/ready/demo/1_4_1_2.html

      2.模板短信SDK使用说明

    • http://doc.yuntongxun.com/p/5a533e0c3b8496dd00dce08c

      3.集成模板短信SDK

    • CCPRestSDK.py:由容联云通讯开发者编写的官方SDK文件,包括发送模板短信的方法

    • ccp_sms.py:调用发送模板短信的方法

    4.模板短信SDK测试

    • ccp_sms.py文件中

    ```python

    -- coding:utf-8 --

    from verifications.libs.yuntongxun.CCPRestSDK import REST

    说明:主账号,登陆云通讯网站后,可在"控制台-应用"中看到开发者主账号ACCOUNT SID

    _accountSid = '8aaf070862181ad5016236f3bcc811d5'

    说明:主账号Token,登陆云通讯网站后,可在控制台-应用中看到开发者主账号AUTH TOKEN

    _accountToken = '4e831592bd464663b0de944df13f16ef'

    请使用管理控制台首页的APPID或自己创建应用的APPID

    _appId = '8aaf070868747811016883f12ef3062c'

    说明:请求地址,生产环境配置成app.cloopen.com

    _serverIP = 'sandboxapp.cloopen.com'

    说明:请求端口 ,生产环境为8883

    _serverPort = "8883"

    说明:REST API版本号保持不变

    _softVersion = '2013-12-26'

    云通讯官方提供的发送短信代码实例

    发送模板短信

    @param to 手机号码

    @param datas 内容数据 格式为数组 例如:{'12','34'},如不需替换请填 ''

    @param $tempId 模板Id

    def sendTemplateSMS(to, datas, tempId): # 初始化REST SDK rest = REST(_serverIP, _serverPort, _softVersion) rest.setAccount(_accountSid, _accountToken) rest.setAppId(_appId)

    result = rest.sendTemplateSMS(to, datas, tempId)
    print(result)
    for k, v in result.items():if k == 'templateSMS':for k, s in v.items():print('%s:%s' % (k, s))else:print('%s:%s' % (k, v))
    

    if name == 'main': # 注意: 测试的短信模板编号为1 sendTemplateSMS('17600992168', ['123456', 5], 1) ```

    5.模板短信SDK返回结果说明

    json { 'statusCode': '000000', // 状态码。'000000'表示成功,反之,失败 'templateSMS': { 'smsMessageSid': 'b5768b09e5bc4a369ed35c444c13a1eb', // 短信唯一标识符 'dateCreated': '20190125185207' // 短信发送时间 } }

    3. 封装发送短信单例类

    1.封装发送短信单例类

    ```python class CCP(object): """发送短信的单例类"""

    def __new__(cls, *args, **kwargs):# 判断是否存在类属性_instance,_instance是类CCP的唯一对象,即单例if not hasattr(CCP, "_instance"):cls._instance = super(CCP, cls).__new__(cls, *args, **kwargs)cls._instance.rest = REST(_serverIP, _serverPort, _softVersion)cls._instance.rest.setAccount(_accountSid, _accountToken)cls._instance.rest.setAppId(_appId)return cls._instance
    

    ```

    2.封装发送短信单例方法

    python def send_template_sms(self, to, datas, temp_id): """ 发送模板短信单例方法 :param to: 注册手机号 :param datas: 模板短信内容数据,格式为列表,例如:['123456', 5],如不需替换请填 '' :param temp_id: 模板编号,默认免费提供id为1的模板 :return: 发短信结果 """ result = self.rest.sendTemplateSMS(to, datas, temp_id) if result.get("statusCode") == "000000": # 返回0,表示发送短信成功 return 0 else: # 返回-1,表示发送失败 return -1

    3.测试单例类发送模板短信结果

    python if __name__ == '__main__': # 注意: 测试的短信模板编号为1 CCP().send_template_sms('17600992168', ['123456', 5], 1)

    4. 知识要点

    1. 容联云通讯只是发送短信的平台之一,还有其他云平台可用,比如,阿里云等,实现套路都是相通的。
    2. 将发短信的类封装为单例,属于性能优化的一种方案。

    短信验证码后端逻辑

    1. 短信验证码接口设计

    1.请求方式

    |选项|方案| |---|---| |请求方法|GET| |请求地址|/sms_codes/(?P1[3-9]\d{9})/|

    2.请求参数:路径参数和查询字符串

    |参数名|类型|是否必传|说明| |---|---|---|---| |mobile|string|是|手机号| |image_code|string|是|图形验证码| |uuid|string|是|唯一编号|

    3.响应结果:JSON

    |字段|说明| |---|---| |code|状态码| |errmsg|错误信息|

    2. 短信验证码接口定义

    ```python class SMSCodeView(View): """短信验证码"""

    def get(self, reqeust, mobile):""":param reqeust: 请求对象:param mobile: 手机号:return: JSON"""pass
    

    ```

    3. 短信验证码后端逻辑实现

    ```python class SMSCodeView(View): """短信验证码"""

    def get(self, reqeust, mobile):""":param reqeust: 请求对象:param mobile: 手机号:return: JSON"""# 接收参数image_code_client = reqeust.GET.get('image_code')uuid = reqeust.GET.get('uuid')# 校验参数if not all([image_code_client, uuid]):return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少必传参数'})# 创建连接到redis的对象redis_conn = get_redis_connection('verify_code')# 提取图形验证码image_code_server = redis_conn.get('img_%s' % uuid)if image_code_server is None:# 图形验证码过期或者不存在return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图形验证码失效'})# 删除图形验证码,避免恶意测试图形验证码try:redis_conn.delete('img_%s' % uuid)except Exception as e:logger.error(e)# 对比图形验证码image_code_server = image_code_server.decode()  # bytes转字符串if image_code_client.lower() != image_code_server.lower():  # 转小写后比较return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '输入图形验证码有误'})# 生成短信验证码:生成6位数验证码sms_code = '%06d' % random.randint(0, 999999)logger.info(sms_code)# 保存短信验证码redis_conn.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)# 发送短信验证码CCP().send_template_sms(mobile,[sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], constants.SEND_SMS_TEMPLATE_ID)# 响应结果return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '发送短信成功'})
    

    ```

    短信验证码前端逻辑

    1. Vue绑定短信验证码界面

    1.register.html

    ```html

  • [[ sms_code_tip ]] [[ error_sms_code_message ]]
  • ```

    2.register.js

    js check_sms_code(){ if(this.sms_code.length != 6){ this.error_sms_code_message = '请填写短信验证码'; this.error_sms_code = true; } else { this.error_sms_code = false; } },

    2. axios请求短信验证码

    1.发送短信验证码事件处理

    ```js send_sms_code(){ // 避免重复点击 if (this.sending_flag == true) { return; } this.sending_flag = true;

    // 校验参数
    this.check_mobile();
    this.check_image_code();
    if (this.error_mobile == true || this.error_image_code == true) {this.sending_flag = false;return;
    }// 请求短信验证码
    let url = '/sms_codes/' + this.mobile + '/?image_code=' + this.image_code+'&uuid='+ this.uuid;
    axios.get(url, {responseType: 'json'
    }).then(response => {if (response.data.code == '0') {// 倒计时60秒var num = 60;var t = setInterval(() => {if (num == 1) {clearInterval(t);this.sms_code_tip = '获取短信验证码';this.sending_flag = false;} else {num -= 1;// 展示倒计时信息this.sms_code_tip = num + '秒';}}, 1000, 60)} else {if (response.data.code == '4001') {this.error_image_code_message = response.data.errmsg;this.error_image_code = true;} else { // 4002this.error_sms_code_message = response.data.errmsg;this.error_sms_code = true;}this.generate_image_code();this.sending_flag = false;}}).catch(error => {console.log(error.response);this.sending_flag = false;})
    

    }, ```

    2.发送短信验证码效果展示

    补充注册时短信验证逻辑

    1. 补充注册时短信验证后端逻辑

    1.接收短信验证码参数

    python sms_code_client = request.POST.get('sms_code')

    2.保存注册数据之前,对比短信验证码

    python redis_conn = get_redis_connection('verify_code') sms_code_server = redis_conn.get('sms_%s' % mobile) if sms_code_server is None: return render(request, 'register.html', {'sms_code_errmsg':'无效的短信验证码'}) if sms_code_client != sms_code_server.decode(): return render(request, 'register.html', {'sms_code_errmsg': '输入短信验证码有误'})

    2. 补充注册时短信验证前端逻辑

    1.register.html

    ```html

  • [[ sms_code_tip ]] [[ error_sms_code_message ]] {% if sms_code_errmsg %} {{ sms_code_errmsg }} {% endif %}
  • ```

    未完待续, 同学们请等待下一期

    全套笔记和代码自取移步gitee仓库: gitee仓库获取完整文档和代码

    感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/691373.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java多线程】线程安全问题与解决方案

目录 1、线程安全问题 1.2、线程安全原因 2、线程加锁 2.1、synchronized 关键字 2.2、完善代码 2.3、对同一个线程的加锁操作 3、内容补充 3.1、内存可见性问题 3.2、指令重排序问题 3.3、解决方法 3.4、总结 volatile 关键字 1、线程安全问题 某个代码&#xff…

初识结构体(C语言)

目录 1、结构体声明 2、结构体访问 3、结构体传参 1、结构体声明 结构是一些值的集合,这些值称为成员变量。结构的每一个成员可以是不同类型的变量。有点像数组,但是一个数组只能存放同一种类型的变量。如果要描述复杂对象的时候,对象由多…

基于Java SSM框架实现留学生交流互动论坛网站项目【项目源码+论文说明】

摘要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存…

基于ant的图片上传组件封装(复制即可使用)

/*** 上传图片组件* param imgSize 图片大小限制* param data 上传数据* param disabled 是否禁用*/import React, { useState,useEffect } from react; import { Upload, Icon, message} from antd; const UploadImage ({imgSize 50,data { Directory: Image },disabled f…

Vue封装全局公共方法

有的时候,我们需要在多个组件里调用一个公共方法,这样我们就能将这个方法封装成全局的公共方法。 我们先在src下的assets里新建一个js文件夹,然后建一个common.js的文件,如下图所示: 然后在common.js里写我们的公共方法,比如这里我们写了一个testLink的方法,然后在main…

Apache Flink连载(三十):Flink 内存模型

🏡 个人主页:IT贫道-CSDN博客 🚩 私聊博主:私聊博主加WX好友,获取更多资料哦~ 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录

【GUI编程】Tkinter之OptionMenu

OptionMenu OptionMenu类是一个辅助类,它用来创建弹出菜单,并且有一恶搞按钮显示它。它非常类似Windows上的下拉列表插件。 如果要获取当前选项菜单的值,你需要把它和一个Tkinter变量联系起来。 def __init__(self, master, variable, val…

“无限交互,全新驾驶体验!智能语音小车,与您共同开创未来出行。”#51单片机最终项目《智能语音小车》【上】

"无限交互,全新驾驶体验!智能语音小车,与您共同开创未来出行。”#51单片机最终项目《智能语音小车》【上】 前言预备知识1. L9110S电机控制器接线1.1 L9110S概述1.2 L9110S IO口描述1.3 L9110S 实物图1.4 L9110S与单片机接线 2. L9110前…

PostgreSQL按日期列创建分区表

在PostgreSQL中,实现自动创建分区表主要依赖于表的分区功能,这一功能从PostgreSQL 10开始引入。分区表可以帮助管理大量数据,通过分布数据到不同的分区来提高查询效率和数据维护的便捷性。以下是在PostgreSQL中自动创建分区表的一般步骤&…

【Git】Gitbash使用ssh 上传本地项目到github

SSH Git上传项目到GitHub(图文)_git ssh上传github-CSDN博客 前提 ssh-keygen -t rsa -C “自己的github电子邮箱” 生成密钥,公钥保存到自己的github的ssh里 1.先创建一个仓库,复制ssh地址 git init git add . git commit -m …

GEE必须会教程—跳舞的线(字符串类型)

字符串,GEE上跳舞的线! GEE学习之路漫长,跟着小编一起走进今天的数据类型的学习。字符串是各大编程语言的常用数据类型,我们今天需要了解GEE平台上字符串的定义、以及常用的方法。 1.定义字符串 //字符串构造 var base_str &q…

「Java同步原理与底层实现解析」

原理概要: java虚拟机中的同步基于进入与结束Monitor对象实现,无论是显式同步(同步代码块进入在jvm是根据monitorenter标志、结束是monitorexit标志,那最后一个是monitorexit是异常结束时被执行的释放指令)、隐式同步…

STM32 输入捕获模式测频率

单片机学习! 目录 文章目录 前言 一、输入捕获测频率配置步骤 二、代码示例及注意事项 2.1 RCC开启时钟 2.2 GPIO初始化 2.3 配置时基单元 2.4 配置输入捕获单元 2.5 选择从模式的触发源 2.6 配置从模式为Reset 2.7 开启定时器 总结 前言 博文介绍如何配置输入捕获电…

OpenAI 全新发布文生视频模型 Sora,支持 60s 超长长度,有哪些突破?将带来哪些影响?

Sora大模型简介 OpenAI 的官方解释了在视频数据基础上进行大规模训练生成模型的方法。 我们下面会摘取其中的关键部分罗列让大家快速get重点。 喜欢钻研的伙伴可以到官网查看技术报告: https://openai.com/research/video-generation-models-as-world-simulator…

AI破局俱乐部,你要了解的都在这里

您好,我是码农飞哥(wei158556),感谢您阅读本文,欢迎一键三连哦。💪🏻 1. Python基础专栏,基础知识一网打尽,9.9元买不了吃亏,买不了上当。 Python从入门到精通…

【C#】使用代码实现龙年春晚扑克牌魔术(守岁共此时),代码实现篇

欢迎来到《小5讲堂》 大家好,我是全栈小5。 这是《C#》系列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握。…

大模型量化技术原理-LLM.int8()、GPTQ

近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,从而导致模型变得越来越大,因此,我们需要一些大模型压缩技术来降低模型部署的成本,并提升模型的推理性能。 模型压缩主要分…

不知如何获取1688工厂档案信息,你还在为此烦恼吗?

阿里巴巴集团旗下的B2B电子商务网站,提供海量优质商品,为采购商和供应商提供交流、合作、采购等服务,是很多没有货源优势的电商卖家首选的货源途径,也是国内最大、货源种类最齐全的货源网站。 不少做跨境电商无货源的朋友都想要1…

用html编写的招聘简历

用html编写的招聘简历 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</tit…

自定义异常处理演示

​ 为了防止黑客从前台异常信息&#xff0c;对系统进行攻击。同时&#xff0c;为了提高用户体验&#xff0c;我们都会都抛出的异常进行拦截处理。 一、全局异常处理 编写一个异常拦截类&#xff0c;如下&#xff1a;ControllerAdvice&#xff0c;很多初学者可能都没有听说过…