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')
最后进行测试:
因为create函数是属于post请求 所以不允许get方法。 这里要注意的是下边的Mobile 允许我们进行测试
我随便输个
返回的格式 是 字段名+ 错误信息
成功的无法测试 因为云片网那边的审核问题我没过 所以 以后有机会在测吧 但是逻辑是这样的