本系列文章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.申请参数:门路参数
参数名类型是否必传阐明
uuidstring惟一编号
3.响应后果:image/jpg

2. 图形验证码接口定义

1.图形验证码视图
class ImageCodeView(View):    """图形验证码"""    def get(self, request, uuid):        """        :param request: 申请对象        :param uuid: 惟一标识图形验证码所属于的用户        :return: image/jpg        """        pass
2.总路由
    # verifications    url(r'^', include('verifications.urls')),
3.子路由
    # 图形验证码    url(r'^image_codes/(?P<uuid>[\w-]+)/$', views.ImageCodeView.as_view()),

图形验证码后端逻辑

1. 筹备captcha扩大包

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

可能呈现的谬误
  • 报错起因:环境中没有Python解决图片的库:PIL

解决办法
  • 装置Python解决图片的库:pip install Pillow

2. 筹备Redis数据库

筹备Redis的2号库存储验证码数据
"verify_code": { # 验证码        "BACKEND": "django_redis.cache.RedisCache",        "LOCATION": "redis://127.0.0.1:6379/2",        "OPTIONS": {            "CLIENT_CLASS": "django_redis.client.DefaultClient",        }    },

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

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
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
<li>    <label>图形验证码:</label>    <input type="text" name="image_code" id="pic_code" class="msg_input">    <img :src="image_code_url" @click="generate_image_code" alt="图形验证码" class="pic_code">    <span class="error_tip">请填写图形验证码</span></li>
3.图形验证码展现和存储成果

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

1.register.html
<li>    <label>图形验证码:</label>    <input type="text" v-model="image_code" @blur="check_image_code" name="image_code" id="pic_code" class="msg_input">    <img :src="image_code_url" @click="generate_image_code" alt="图形验证码" class="pic_code">    <span class="error_tip" v-show="error_image_code">[[ error_image_code_message ]]</span></li>
2.register.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文件中
    # -*- 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返回后果阐明
{    'statusCode': '000000', // 状态码。'000000'示意胜利,反之,失败    'templateSMS':         {            'smsMessageSid': 'b5768b09e5bc4a369ed35c444c13a1eb', // 短信惟一标识符            'dateCreated': '20190125185207' // 短信发送工夫        }}

3. 封装发送短信单例类

1.封装发送短信单例类
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.封装发送短信单例办法
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.测试单例类发送模板短信后果
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.申请参数:门路参数和查问字符串
参数名类型是否必传阐明
mobilestring手机号
image_codestring图形验证码
uuidstring惟一编号
3.响应后果:JSON
字段阐明
code状态码
errmsg错误信息

2. 短信验证码接口定义

class SMSCodeView(View):    """短信验证码"""    def get(self, reqeust, mobile):        """        :param reqeust: 申请对象        :param mobile: 手机号        :return: JSON        """        pass

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

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
<li>    <label>短信验证码:</label>    <input type="text" v-model="sms_code" @blur="check_sms_code" name="sms_code" id="msg_code" class="msg_input">    <a @click="send_sms_code" class="get_msg_code">[[ sms_code_tip ]]</a>    <span class="error_tip" v-show="error_sms_code">[[ error_sms_code_message ]]</span></li>
2.register.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.发送短信验证码事件处理
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 { // 4002                    this.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.接管短信验证码参数
sms_code_client = request.POST.get('sms_code')
2.保留注册数据之前,比照短信验证码
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
<li>    <label>短信验证码:</label>    <input type="text" v-model="sms_code" @blur="check_sms_code" name="sms_code" id="msg_code" class="msg_input">    <a @click="send_sms_code" class="get_msg_code">[[ sms_code_tip ]]</a>    <span v-show="error_sms_code" class="error_tip">[[ error_sms_code_message ]]</span>    {% if sms_code_errmsg %}        <span class="error_tip">{{ sms_code_errmsg }} </span>    {% endif %}</li>

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

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

感兴趣的小伙伴能够自取哦,欢送大家点赞转发~