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

【leetcode】常用数学题解法介绍

当涉及到ACM算法题中常见的数学常识和知识点时,以下是更加详细和全面的分析: 二进制: 二进制在计算机中是最基础的进制,它只包含两个数字0和1。在ACM算法题中,常用的二进制操作有: 位运算:包括…

关于三色标记算法

关于三色标记算法 三色标记算法是一种用于垃圾收集得算法,主要用于解决在并发垃圾收集中可能出现得对象引用更新问题。在JVM中,这种算法主要应用于CMS(ConcurrentMarkSweep)收集器和G1(Garbage-first)收集…

基于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…

【LeetCode+JavaGuide打卡】Day19|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

学习目标: 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树 学习内容: 654.最大二叉树 题目链接&&文章讲解 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&…

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

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

java基础 -- 事件监听器

要实现一个事件监听器,您可以使用Java中的事件模型和接口。以下是一个简单的示例,演示如何创建和使用一个事件监听器: 创建事件类(Event Class): import java.util.EventObject;public class MyEvent ext…

ComfyUI添加IP白名单功能

AI生图很火,相信你对ComfyUI不陌生,查看ComfyUI的源码可以发现它是使用aiohttp来作为服务端的。那么我们在使用ComfyUI的时候可能需要做一些安全的限制,接下来我们将探讨如何在 ComfyUI 中添加 IP 白名单功能,以确保只有特定的用户…

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…

C#面:.NET中所有类型的基类是什么

System.Object 是C# .NET中所有类型的基类,它提供了一些通用的方法和属性,以及对象的类型信息和引用比较等功能。 例如:System.ObjectToString(),Equals(),GetHashCode() 等。 由于所有类型都继承自 System.Object&a…

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

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

图像预处理技术与算法

图像预处理是计算机视觉和图像处理中非常关键的第一步,其目的是为了提高后续算法对原始图像的识别、分析和理解能力。以下是一些主要的图像预处理技术: 1.图像增强: 对比度调整:通过直方图均衡化(Histogram Equalization)等方法改善图像整体或局部的对比度。 伽玛校正:…

MT4技术分析工具介绍:让你更好地把握市场趋势

在外汇交易市场中,技术分析是一种常用的分析手段,而MT4作为外汇交易中广泛使用的交易平台,拥有丰富的技术分析工具,能够帮助交易者更好地把握市场趋势。本文将介绍几款常用的MT4技术分析工具,帮助读者更好地理解和运用…