小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Django blog項(xiàng)目《六》:《注冊(cè)功能1》用戶模型、用戶名、手機(jī)號(hào)、圖形驗(yàn)證碼、短信驗(yàn)證碼功能實(shí)現(xiàn)

 看見(jiàn)就非常 2020-04-29

用戶模塊分析已經(jīng)完成,那么接下來(lái)就是具體的代碼實(shí)現(xiàn)了,這一章主要完成用戶模型設(shè)計(jì)和圖形驗(yàn)證碼、用戶名和手機(jī)號(hào)驗(yàn)證的完成。

一、用戶模型設(shè)計(jì)

用戶模型使用django自帶的auth中的AbstractUser來(lái)進(jìn)行改寫(xiě),

  1. 添加手機(jī)號(hào)字段
  2. 添加郵箱狀態(tài)字段

具體實(shí)現(xiàn)過(guò)程:在 users app 里面的 models.py 里面進(jìn)行用戶模型的修改

1. 對(duì)創(chuàng)建超級(jí)用戶時(shí)需要輸入email字段

users/models.py

from django.db import models
from django.contrib.auth.models import UserManager as _UserManager


class UserManager(_UserManager):
    """
    重寫(xiě)創(chuàng)建超級(jí)用戶時(shí)需要輸入email字段
    """
    def create_superuser(self, username, password, email=None, **extra_fields):

        return super().create_superuser(username=username, password=password, email=email, **extra_fields)

2. 添加mobile和email_active字段

users/models.py

from django.contrib.auth.models import AbstractUser

class Users(AbstractUser):
    """
    重寫(xiě)users模型
    """
    objects = UserManager()
    mobile = models.CharField(
        max_length=11,
 
        help_text="手機(jī)號(hào)",
        verbose_name="手機(jī)號(hào)",
        error_messages={
            "unique": "手機(jī)號(hào)已被注冊(cè)"
        })
    email_active = models.BooleanField(default=False, help_text="郵箱狀態(tài)")

    class Meta:
        db_table = "tb_users"  # 數(shù)據(jù)庫(kù)名
        verbose_name = "用戶"  # 指明在admin站點(diǎn)中的名字
        verbose_name_plural = verbose_name  # 顯示復(fù)數(shù)名稱

    def __str__(self):
        return self.username
3. 對(duì)Users模型進(jìn)行settings.py配置

自定義的Users模型需要進(jìn)行配置后才能使用。

settings.py

# 配置自定義的用戶模型

AUTH_USER_MODEL = "users.Users"

二、圖形驗(yàn)證碼

在用戶注冊(cè)時(shí)很多字段驗(yàn)證在后續(xù)的其他項(xiàng)目時(shí)還能使用,為了復(fù)用這里重新新建一個(gè)app專門(mén)用來(lái)做用戶注冊(cè)的用戶名、手機(jī)號(hào)、圖形驗(yàn)證碼、短信驗(yàn)證碼的驗(yàn)證。

創(chuàng)建1個(gè)新的app verifications,拉到apps里面去。

1. 路由urls.py設(shè)置
  1. 項(xiàng)目下面的 urls.py

    from django.urls import path, include
    
    urlpatterns = [
        path('', include("verifications.urls")),
    ]
    
  2. 應(yīng)用 verifications/urls.py配置

    from django.urls import re_path
    from verifications import views
    
    
    app_name = "verifications"
    
    urlpatterns = [
        re_path("image_code/<uuid:image_code_id>/", views.ImageCodes.as_view(), name="image_code"),
    
    ]
    
2. JS前端實(shí)現(xiàn)

注冊(cè)功能的js代碼不單獨(dú)放,都統(tǒng)一放在register.js里面

users/register.js

$(function () {
    let $img = $('.form-item .captcha-graph-img img'); //獲取圖片信息
    let sImageCodeId='';  //定義一個(gè)空字符串用來(lái)放uuid字符串

    generateImageCode();
    // 當(dāng)點(diǎn)擊驗(yàn)證碼時(shí)刷新驗(yàn)證碼
    $img.click(generateImageCode);


    // 生成圖片UUID驗(yàn)證碼
    function generateUUID() {
        let d = new Date().getTime();
        if (window.performance && typeof window.performance.now === "function") {
            d += performance.now(); //use high-precision timer if available
        }
        let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            let r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c==='x' ? r : (r & 0x3 | 0x8)).toString(16);
        });
        return uuid;
    }

    //生成驗(yàn)證碼圖片
    function generateImageCode() {
        sImageCodeId = generateUUID();  //這里不能有l(wèi)et這相當(dāng)于對(duì)前面的sImageCodeId進(jìn)行修改
        // console.log("第一個(gè)uuid:"+sImageCodeId);
        let imageCodeUrl = '/image_code/'+sImageCodeId+'/';  //拼接圖片驗(yàn)證碼請(qǐng)求路徑
        $img.attr('src',imageCodeUrl);  //給圖片添加src鏈接 路徑

    }
});
3. views.py邏輯實(shí)現(xiàn)

圖形驗(yàn)證碼需要使用圖形驗(yàn)證碼插件,網(wǎng)上有很多現(xiàn)成的代碼,這里可以在獲取captcha圖形驗(yàn)證碼插件

在前面settings.py配置redis數(shù)據(jù)庫(kù)時(shí)只設(shè)置了一個(gè)為default默認(rèn)0數(shù)據(jù)庫(kù),將圖形驗(yàn)證碼和短信驗(yàn)證碼的放在為verify_code的1數(shù)據(jù)庫(kù)

settings.py中添加驗(yàn)證碼存放的數(shù)據(jù)庫(kù)

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/0',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient'
        }
    },
    # 新添加存放短信驗(yàn)證碼和圖形驗(yàn)證碼
    'verify_code': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient'
        }
    },
}

verifications/views.py

import logging

from django.views import View
from django.http import HttpResponse
from django_redis import get_redis_connection

from verifications import contains
from utils.captcha.captcha import captcha


logger = logging.getLogger("django")


class ImageCodes(View):
    """
    create image_code view
    """
    def get(self, request, image_code_id):  # 從前端獲取到傳過(guò)來(lái)的參數(shù)uuid
        verify_text, verify_image = captcha.generate_captcha()  # 生成驗(yàn)證碼文本和圖片

        # 鏈接redis步驟 將生成的驗(yàn)證碼文本和圖片保存到redis中

        # 1.鏈接redis區(qū)
        redis_obj = get_redis_connection(alias="verify_code")

        # 2. 構(gòu)造鍵值對(duì)
        verify_key = "image_{}".format(image_code_id)

        # 3. 保存數(shù)據(jù)到redis并設(shè)置有效期
        redis_obj.setex(verify_key, contains.IMAGE_CODE_EXPIRE_TIME, verify_text)

        logger.info('verify_text:{}'.format(verify_text))  # 后臺(tái)顯示驗(yàn)證碼信息

        return HttpResponse(content=verify_image, content_type='image/jpg')   # 把驗(yàn)證碼圖片返回到前端

三、用戶名

1. 路由urls.py設(shè)置

verification/urls.py

from django.urls import re_path
from verifications import views


app_name = "verifications"

urlpatterns = [
    re_path("username/(?P<username>\w{6,18})/", views.CheckUsernameView.as_view(), name="username"),
]
2. JS前端實(shí)現(xiàn)

users/register.js

$(function () {
    
    let $username = $('#user_name');  //獲取用戶名標(biāo)簽

    //鼠標(biāo)移出用戶名輸入框時(shí)執(zhí)行判斷
    $username.blur(function () {
        fn_check_username();
    });

    // 用戶名是否存在
    function fn_check_username() {
        let sUsername = $username.val(); //獲取表單數(shù)據(jù)
        let sReturnValue = '';
        // 前端校驗(yàn)
        if (sUsername === ""){
            // alert("用戶名不能為空") ;
            // alert('用戶名能為空!');  //這里需要改進(jìn)
            return
        }else if(!(/\w{6,18}/).test(sUsername)){
            // alert('請(qǐng)輸入6~18位字符的用戶名!');  //這里需要改進(jìn)
            return
        }

        //ajax請(qǐng)求判斷數(shù)據(jù)庫(kù)是否存在  后端校驗(yàn)
        $.ajax({
            url:'/username/' + sUsername +'/',
            type:'GET',
            dataType:'json',
            async: false,  // 關(guān)閉異步
            success:function (arg) {
                if(arg.data.count !== 0){  // 不等于0表示已經(jīng)注冊(cè)了
                    // alert("用戶名已注冊(cè),請(qǐng)重新輸入")
                    sReturnValue = "";
                }else{
                    sReturnValue="success";
                    alert("用戶名可以正常使用")
                }
            },
            error:function(){
                alert("用戶名ajax,服務(wù)器超時(shí),請(qǐng)重新輸入");
                sReturnValue = "";
            }
        });

        return sReturnValue  //返回出該信息
    }
});
3. view.py邏輯實(shí)現(xiàn)

verifications/views.py

from django.views import View
from django.http import JsonResponse

from users import models

class CheckUsernameView(View):
    """
    create username verify view

    # 1. 創(chuàng)建一個(gè)類
    request: GET
    params: username
    """
    # 2. 創(chuàng)建個(gè)get方法來(lái)處理邏輯
    def get(self, request, username):

        # 3. 從數(shù)據(jù)庫(kù)中查看是否存在該用戶
        data = {
            "username": username,
            "count": models.Users.objects.filter(username=username).count()  # 獲取數(shù)據(jù)庫(kù)中有幾條這個(gè)信息:無(wú)則0
        }

        # 4. 返回到前端
        return JsonResponse(data=data)

四、手機(jī)號(hào)

1. 路由urls.py設(shè)置

verification/urls.py

from django.urls import re_path
from verifications import views


app_name = "verifications"

urlpatterns = [
    re_path("mobile/(?P<mobile>1[3-9]\d{11})/", views.CheckMobileView.as_view(), name="mobile"),
]
2. JS前端實(shí)現(xiàn)

users/register.js

$(function () {
   
    let $mobile = $("#mobile"); //獲取手機(jī)號(hào)
    
    //鼠標(biāo)移出手機(jī)號(hào)輸入框時(shí)執(zhí)行判斷
    $mobile.blur(function() {
        fn_check_mobile();
    });

    // 手機(jī)號(hào)是否存在
    function fn_check_mobile(){
        let sMobile = $mobile.val();
        let sReturnMobileValue = "";
        // 前端校驗(yàn)
        if (sMobile === ""){
            // alert("手機(jī)號(hào)輸入為空");
            alert("手機(jī)號(hào)為空");

        }else if(!(/^1[3-9]\d{9}/).test(sMobile)){
            alert("請(qǐng)輸入正確的手機(jī)號(hào)格式") ;

        }
        //ajax請(qǐng)求判斷數(shù)據(jù)庫(kù)是否存在  后端校驗(yàn)
        $.ajax({
            url:"/mobile/"+sMobile+'/',
            type:"GET",
            dataType: "json",
            async:false,  // 關(guān)閉異步
            success:function (arg) {
                if(arg.data.count !== 0){
                    alert(sMobile+"手機(jī)號(hào)已被注冊(cè),請(qǐng)重新輸入");
                    sReturnMobileValue = "";
                }else{
                    alert(sMobile+"手機(jī)號(hào)能正常使用");
                    sReturnMobileValue = "success";
                }
            },
            error:function () {
                alert("手機(jī)號(hào)ajax,服務(wù)器超時(shí),請(qǐng)重新輸入");
                sReturnMobileValue = "";
            }
        });
        return sReturnMobileValue  //返回出該信息
    }
});
3. view.py邏輯實(shí)現(xiàn)

verifications/views.py

from django.views import View
from django.http import HttpResponse, JsonResponse

from users import models

class CheckMobileView(View):
    """
    create mobile verify view

    # 1.創(chuàng)建一個(gè)類
    request: GET
    params: mobile
    """
    # 2. 創(chuàng)建個(gè)get方法來(lái)處理邏輯
    def get(self, request, mobile):
        # 3. 從數(shù)據(jù)庫(kù)中查看是否存在該用戶
        data = {
            "mobile": mobile,
            "count": models.Users.objects.filter(mobile=mobile).count()
        }
        # 5. 返回到前端

        return JsonResponse(data=data)

五、短信驗(yàn)證碼

1. 路由urls.py設(shè)置

verification/urls.py

from django.urls import re_path
from verifications import views


app_name = "verifications"

urlpatterns = [
    re_path("sms_code/", views.SmsCodeView.as_view(), name="sms_code"),
]
2. JS前端實(shí)現(xiàn)

users/register.js

$(function () {
    let sImageCodeId='';  //定義一個(gè)空字符串用來(lái)放uuid字符串
    let $mobile = $("#mobile"); //獲取手機(jī)號(hào)
    let $smsCodeBtn = $(".form-item .sms-captcha");  //發(fā)送短信驗(yàn)證按鈕
    let $smsCodeText = $(".form-item .form-captcha");    //圖形驗(yàn)證碼輸入框文本
   


    //短信驗(yàn)證
    $smsCodeBtn.click(function(){
        // 判定手機(jī)號(hào)是否有輸入
        if ( fn_check_mobile() !== "success"){
            alert("手機(jī)號(hào)為空");
            return
        }
        
        // 判斷用戶是否輸入圖形驗(yàn)證碼
        let text = $smsCodeText.val();
        if (!text){
            alert("請(qǐng)輸入圖形驗(yàn)證碼");
            return
        }

        // 判斷UUID
        if(!sImageCodeId){
            console.log("第2個(gè)"+sImageCodeId);
            alert("圖形UUID不對(duì)");
            return
        }
        
        let dataParams={
            'mobile':$mobile.val(),
            'image_text':text,
            "image_code_id":sImageCodeId,
        };
        
        $.ajax({
            url:"/sms_code/",
            type:"POST",
            data:JSON.stringify(dataParams),
            success:function(arg){
                console.log(arg);
                if(arg.errno==="200"){   // errno: "200", errmsg: "短信發(fā)送正常", data: null
                    alert("短信驗(yàn)證碼發(fā)送成功");
                    //倒計(jì)時(shí)功能
                    let num = 60;
                    // 設(shè)置計(jì)時(shí)器
                    let t = setInterval(function () {
                        if (num===1){
                            clearInterval(t);
                            $smsCodeBtn.html("重新發(fā)送驗(yàn)證碼")
                        }else{
                            num -= 1;
                            //展示倒計(jì)時(shí)信息
                            $smsCodeBtn.html(num+"秒");
                        }

                    },1000)
                }else{
                    alert(arg.errmsg);
                }
            },
            error:function(){
                alert("短信驗(yàn)證ajax,服務(wù)器超時(shí),請(qǐng)重試")
            }
        })
    });
});
3. view.py邏輯實(shí)現(xiàn)

在寫(xiě)代碼時(shí)需要很多錯(cuò)誤代碼和錯(cuò)誤代碼的意思,這里單獨(dú)建一個(gè)文件用來(lái)放這個(gè)錯(cuò)誤代碼,同時(shí)后續(xù)在寫(xiě)代碼時(shí)需要很多時(shí)候傳遞給前端一個(gè)json格式的文件,包含錯(cuò)誤代碼,這樣前端才能做好判斷。

在utlis下面創(chuàng)建一個(gè)res_code文件夾,創(chuàng)建一個(gè) res_code.py文件用來(lái)放錯(cuò)誤代碼, json_function.py用來(lái)放置轉(zhuǎn)化json格式的插件:

utils/res_code/res_code.py

class Code:
    OK = "200"
    DBERR = "4001"
    NODATA = "4002"
    DATAEXIST = "4003"
    DATAERR = "4004"
    METHERR = "4005"
    SMSERROR = "4006"
    SMSFAIL = "4007"

    SESSIONERR = "4101"
    LOGINERR = "4102"
    PARAMERR = "4103"
    USERERR = "4104"
    ROLEERR = "4105"
    PWDERR = "4106"

    SERVERERR = "4500"
    UNKOWNERR = "4501"


error_map = {
    Code.OK: "成功",
    Code.DBERR: "數(shù)據(jù)庫(kù)查詢錯(cuò)誤",
    Code.NODATA: "無(wú)數(shù)據(jù)",
    Code.DATAEXIST: "數(shù)據(jù)已存在",
    Code.DATAERR: "數(shù)據(jù)錯(cuò)誤",
    Code.METHERR: "方法錯(cuò)誤",
    Code.SMSERROR: "發(fā)送短信驗(yàn)證碼異常",
    Code.SMSFAIL: "發(fā)送短信驗(yàn)證碼失敗",

    Code.SESSIONERR: "用戶未登錄",
    Code.LOGINERR: "用戶登錄失敗",
    Code.PARAMERR: "參數(shù)錯(cuò)誤",
    Code.USERERR: "用戶不存在或未激活",
    Code.ROLEERR: "用戶身份錯(cuò)誤",
    Code.PWDERR: "密碼錯(cuò)誤",

    Code.SERVERERR: "內(nèi)部錯(cuò)誤",
    Code.UNKOWNERR: "未知錯(cuò)誤",
}

utils/res_code/json_funciton.py

from django.http import JsonResponse

from utils.res_code.res_code import Code


# 處理json格式轉(zhuǎn)化,并加入異常碼和異常信息
def to_json_data(errno=Code.OK, errmsg='', data=None, **kwargs):
    """
    返回給前端 json數(shù)據(jù)以及錯(cuò)誤信息
    :param errno: 錯(cuò)誤代碼
    :param errmsg: 錯(cuò)誤信息
    :param data: 參數(shù)
    :param kwargs: 不定長(zhǎng)數(shù)據(jù)
    :return:
    """
    json_dict = {'errno': errno, 'errmsg': errmsg, 'data': data}

    if kwargs:
        json_dict.update(kwargs)

    return JsonResponse(json_dict)

verifications/contains.py

# -*- coding: utf-8 -*-
"""
@Time    : 2020/2/26 21:29
@Author  : 半紙梁
@File    : contains.py
"""

IMAGE_CODE_EXPIRE_TIME = 5*60  # 圖形驗(yàn)證碼有效時(shí)間

SMS_CODE_EXPIRE_TIME = 5*60   # 短信驗(yàn)證碼有效時(shí)間

SMS_REPEAT_EXPIRE_TIME = 60   # 可重復(fù)發(fā)送短信的時(shí)間

SMS_TEMPLATE = 1   # 短信發(fā)送模板

SMS_CCP_EXPIRE_TIME = 5   # 云通訊短信有效時(shí)間 以分鐘計(jì)算的

verifications/views.py

import logging
import json
import random

from django.views import View
from django_redis import get_redis_connection

from verifications import contains
from verifications.forms import SmsCodeForm
from utils.yuntongxun.sms import CCP
from utils.res_code.json_function import to_json_data
from utils.res_code.res_code import Code, error_map

logger = logging.getLogger("django")

class SmsCodeView(View):
    """
    # 1. 創(chuàng)建一個(gè)SmsCodeView類
    param: mobile、image_text、image_code_id
    """
    # 2. 創(chuàng)建一個(gè)post方法用來(lái)處理邏輯
    def post(self, request):
        # 3. 獲取前端傳來(lái)的數(shù)據(jù)
        json_data = request.body

        # 4. 將數(shù)據(jù)轉(zhuǎn)化為字典
        dict_data = json.loads(json_data)

        # 5. 將數(shù)據(jù)傳遞給SmsCodeForm表單進(jìn)行校驗(yàn)
        form = SmsCodeForm(data=dict_data)

        # 6. 校驗(yàn)成功處理方式
        if form.is_valid():
            # 7. 獲取校驗(yàn)后的數(shù)據(jù)
            mobile = form.cleaned_data.get("mobile")

            # 8. 生成短信驗(yàn)證碼
            sms_text = "%06d" % random.randint(0, 999999)

            # 9. 將短信驗(yàn)證碼和和過(guò)期時(shí)間保存到redis中
            redis_obj = get_redis_connection("verify_code")
            sms_text_key = "sms_code_{}".format(mobile).encode("utf8")
            sms_repeat_key = "sms_sixty_{}".format(mobile).encode("utf8")

            redis_obj.setex(sms_text_key, contains.SMS_CODE_EXPIRE_TIME, sms_text)  # key, expire_time, value
            redis_obj.setex(sms_repeat_key, contains.SMS_CODE_EXPIRE_TIME, contains.SMS_REPEAT_EXPIRE_TIME)

            # logging.info("發(fā)送短信正常[mobile:%s sms_num:%s]" % (mobile, sms_num))  # 調(diào)試代碼時(shí)候用,在控制臺(tái)顯示

            # 9. 使用用通訊插件發(fā)送短信
            try:
                result = CCP().send_Template_sms(mobile, [sms_text, contains.SMS_CCP_EXPIRE_TIME], contains.SMS_TEMPLATE)
            except Exception as e:
                logger.error("短信發(fā)送異常[mobile:{},error:{}]".format(mobile, e))
                return to_json_data(errno=Code.SMSERROR, errmsg=error_map[Code.SMSERROR])  # 短信發(fā)送異常
            else:
                if result == 0:  # 發(fā)送成功
                    logger.info("短信發(fā)送成功[mobile:{},sms_code:{}]".format(mobile, sms_text))
                    return to_json_data(errmsg="短信發(fā)送正常")
                else:  # 發(fā)送失敗
                    logger.warning("短信發(fā)送失敗[mobile:{}]".format(mobile))
                    return to_json_data(errno=Code.SMSFAIL, errmsg=error_map[Code.SMSFAIL])

        # 校驗(yàn)未通過(guò)
        else:
            err_msg_list = []

            for item in form.errors.values():
                err_msg_list.append(item[0])

            err_info = '/'.join(err_msg_list)
            return to_json_data(errno=Code.PARAMERR, errmsg=err_info)



verifications/forms.py

# -*- coding: utf-8 -*-
"""
@Time    : 2020/2/27 9:49
@Author  : 半紙梁
@File    : forms.py
"""
from django import forms
from django_redis import get_redis_connection
from django.core.validators import RegexValidator


mobile_reg = RegexValidator(r"^1[3-9]\d{9}","手機(jī)號(hào)格式不正確")


class SmsCodeForm(forms.Form):
    """
    check sms_code field
    字段一定要和js中傳遞過(guò)來(lái)的保持一樣
    """
    mobile = forms.CharField(
        max_length=11,
        min_length=11,
        validators=[mobile_reg],
        error_messages={
            "max_length": "手機(jī)號(hào)格式不正確",
            "min_length": "手機(jī)號(hào)格式不正確",
            "required": "手機(jī)號(hào)不能為空"
        }
    )

    image_code_id = forms.UUIDField(error_messages={"required": "UUID不能為空"})  # 
    image_text = forms.CharField(
        max_length=4,
        min_length=4,
        error_messages={
            "max_length": "圖形驗(yàn)證碼格式不正確",
            "min_length": "圖像驗(yàn)證碼格式不正確",
            "required": "圖形驗(yàn)證碼不能為空"
        }
    )

    def clean(self):
        # 1. 獲取清洗后的數(shù)據(jù)
        cleaned_data = super().clean()
        mobile = cleaned_data.get("mobile")
        image_code_uuid = cleaned_data.get("image_code_id")
        image_text = cleaned_data.get("image_text")

        # 2. 建立redis鏈接
        try:
            redis_obj = get_redis_connection("verify_code")
        except Exception as e:
            raise forms.ValidationError("redis數(shù)據(jù)庫(kù)連接錯(cuò)誤")

        # 3. 構(gòu)建image_code查詢的鍵
        image_code_key = "image_{}".format(image_code_uuid).encode("utf8")

        # 4. 獲取數(shù)據(jù)庫(kù)中的image_code的值
        redis_byte_image_text = redis_obj.get(image_code_key)

        # 5. 刪除redis中該uuid的鍵
        redis_obj.delete(image_code_key)  #

        # 6. 將拿到的值化為utf8字符:redis中拿到的值都是二進(jìn)制
        redis_image_text = redis_byte_image_text.decode("utf8") if redis_byte_image_text else None

        # 7. 判斷現(xiàn)在的image_text和redis_image_text是否一致
        if image_text.upper() != redis_image_text:
            raise forms.ValidationError("圖形驗(yàn)證碼校驗(yàn)失敗")

        # 8. 判斷60秒內(nèi)是否有重復(fù)發(fā)送短信
        redis_sms_repeat_key = "mobile_{}".format(mobile).encode("utf8")  # 構(gòu)建短信60秒內(nèi)發(fā)送查詢的鍵
        if redis_obj.get(redis_sms_repeat_key):
            raise forms.ValidationError("短信發(fā)送太頻繁,請(qǐng)稍后再試")

    

用戶注冊(cè)功能點(diǎn)擊注冊(cè)放在users app里面進(jìn)行完成。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多