欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Vue + Django 2.0.6 学习笔记 7.8-9 drf实现发送短信验证码接口

程序员文章站 2022-07-14 22:30:05
...

首先在users这个app下新建serializers.py用来验证表单

# encoding:utf-8
__date__ = '2019-06-11 13:47'

import re
from datetime import datetime, timedelta

from rest_framework import serializers

# 通过 get_user_model 获得settings中AUTH_USER_MODEL的值

from django.contrib.auth import get_user_model

User = get_user_model()

from MxShop.settings import REGEX_MOBILE
from .models import VerifyCode


# 不继承ModelSerializer的原因是 现在还没有code字段数据 如果用ModelSerializer的话就需要验证code了 所以现在采用自定义验证的方式

class SmsSerializer(serializers.Serializer):
    mobile = serializers.CharField(max_length=11)

    def validate_mobile(self, mobile):
        """
        验证手机号码
        :param mobile:
        :return: mobile
        """
        # 验证手机号是否已注册
        if User.objects.filter(mobile=mobile).count():
            raise serializers.ValidationError('用户已经存在')

        # 验证手机号是否合法
        # 这里的REGEX_MOBILE是自定义的正则表达式规则
        if not re.match(REGEX_MOBILE, mobile):
            raise serializers.ValidationError("手机号码非法")

        # 验证码发送频率
        one_mintes_ago = datetime.now() - timedelta(hours=0, minutes=1, seconds=0)
        if VerifyCode.objects.filter(add_time__gt = one_mintes_ago, mobile=mobile).count():
            raise serializers.ValidationError("距离上一次发送未超过60s")

        return mobile

"""
以下是 VerifyCode Model类的展示 以作参考
class VerifyCode(models.Model):
    """
    """
    短信验证码
    """
    """
    code = models.CharField(max_length=10, verbose_name=u'验证码')
    mobile = models.CharField(max_length=11, verbose_name=u'电话')
    add_time = models.DateTimeField(default=datetime.now, verbose_name=u'添加时间')

    class Meta:
        verbose_name = u'短信验证码'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.code
"""

Settings.py:

#手机号合法验证正则表达式(根据现在的情况自己改下 好像现在有199 190之类的号码了)
REGEX_MOBILE = "^1[358]\d{9}$|^147\d{8}$|^17[67]\d{8}$"

#云片网设置 将APIKEY设置到settings中 方便其他地方获取。
APIKEY = 'jfwefw23r232'

Serializers类写好之后就可以去写view了

from rest_framework import viewsets, status
from rest_framework.response import Response
from random import choices

from .serializers import SmsSerializer
# 这里就是刚才settings中设置的APIKEY
from MxShop.settings import APIKEY
from .models import VerifyCode

from utils.yunpin import YunPian


class SmsCodeViewset(CreateModelMixin, viewsets.GenericViewSet):
    """
    发送短信验证码
    """
    serializer_class = SmsSerializer

    def generate_code(self):
        """
        生成4位数的验证码
        :return:
        """
        seeds = "1234567890"
        random_str = []
        for i in range(4):
            random_str.append(choices(seeds))
        return "".join(random_str)

# 这里的create函数是将CreateModelMixin中的create函数copy过来重写的

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        # 装载SmsSerializer类进行校验
        # 如果is_valid中的raise_exception设置为True 则自定义的serializer中有错的话直接抛异常 返回400
        serializer.is_valid(raise_exception=True)

        mobile = serializer.validated_data['mobile']

        yun_pian = YunPian(APIKEY)

        code = self.generate_code()

        # 根据云片网的api文档中表示如果发送成功返回0和msg消息
        sms_status = yun_pian.send_sms(code = code, mobile=mobile)



        if sms_status["code"] != 0:
            return Response({
                "mobile": sms_status["msg"]
            }, status=status.HTTP_400_BAD_REQUEST)
        else:
            # 201状态表示创建成功
            code_record = VerifyCode(code = code, mobile=mobile)
            code_record.save()
            return Response({
                "mobile":mobile
            }, status=status.HTTP_201_CREATED)

        # 这下面这些是CreateModelMixin中的create函数的内容 不动他就是了
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

接着是配置路由:

urls.py

from users.views import SmsCodeViewset

router.register(r'codes', SmsCodeViewset, base_name='codes')

最后进行测试:

Vue + Django 2.0.6 学习笔记 7.8-9 drf实现发送短信验证码接口

因为create函数是属于post请求 所以不允许get方法。 这里要注意的是下边的Mobile  允许我们进行测试 

我随便输个

Vue + Django 2.0.6 学习笔记 7.8-9 drf实现发送短信验证码接口

返回的格式 是 字段名+ 错误信息

成功的无法测试 因为云片网那边的审核问题我没过 所以 以后有机会在测吧 但是逻辑是这样的