本文共 3914 字,大约阅读时间需要 13 分钟。
首先在users这个app下新建serializers.py用来验证表单
# encoding:utf-8__date__ = '2019-06-11 13:47'import refrom datetime import datetime, timedeltafrom rest_framework import serializers# 通过 get_user_model 获得settings中AUTH_USER_MODEL的值from django.contrib.auth import get_user_modelUser = get_user_model()from MxShop.settings import REGEX_MOBILEfrom .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, statusfrom rest_framework.response import Responsefrom random import choicesfrom .serializers import SmsSerializer# 这里就是刚才settings中设置的APIKEYfrom MxShop.settings import APIKEYfrom .models import VerifyCodefrom utils.yunpin import YunPianclass 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 SmsCodeViewsetrouter.register(r'codes', SmsCodeViewset, base_name='codes')
最后进行测试:
因为create函数是属于post请求 所以不允许get方法。 这里要注意的是下边的Mobile 允许我们进行测试
我随便输个
返回的格式 是 字段名+ 错误信息
成功的无法测试 因为云片网那边的审核问题我没过 所以 以后有机会在测吧 但是逻辑是这样的
转载地址:http://jiepi.baihongyu.com/