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

首先在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')

最后进行测试:

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

我随便输个

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

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@凌晨三点半

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值