drf–验证前端传递过来的数据
-
前端传来的数据先走mixins,然后进行验证,验证通过后,就会调用ModelSerializer的create或者update方法,如果继承的是Serializer,就需要自己重载Serializer中的create或者update方法,或者修改mixins的create等方法的逻辑进行保存。
-
serializer和form一样, 验证都是在serializer和form里验证
-
views–重写了CreateModelMixin下的create方法
from rest_framework.mixins import CreateModelMixin from rest_framework import viewsets # 返回的响应体 from rest_framework.response import Response # 状态码 from rest_framework import status from .models import VerifyCode from .serializers import SmsSerializer from MxShop.settings import API_KEY from utils.yunpian import YunPian class SmsCodeViewSet(CreateModelMixin, viewsets.GenericViewSet): """ 发送短信验证码 """ # 指定序列化类 serializer_class = SmsSerializer # 生成验证码 def generate_code(self): """ 生成4位的验证码 :return: 验证码 """ seeds = "1234567890" code = "" for i in range(4): code += random.choice(seeds) return code # 重写创建方法 def create(self, request, *args, **kwargs): # 这个serializer就是我们指定的serializer serializer = self.get_serializer(data=request.data) # raise_exception=True 表示验证失败 直接抛异常 不会往下走了 serializer.is_valid(raise_exception=True) # 上面那两行代码必须 # 取出手机号码 # validated_data保存着前端传递过来的数据 mobile = serializer.validated_data["mobile"] # 获取验证码 code = self.generate_code() # 接入云片网发送短信 # 创建对象, 传入APIKEY 这个APIKEY是你云片网账号里面的APIKEY 我把它设置在settings里面了 # 怎么接入片云网和调用片云网的接口, 我在其他博客写过, 可以去看一下 yunpian = YunPian(API_KEY) sms_status = yunpian.send_sms(code=code, mobile=mobile) # 返回结果code为0表示发送成功 if sms_status["code"] != 0: # 返回失败原型 return Response({ # 手机号 "mobile": sms_status["mobile"] # 状态码 }, status=status.HTTP_400_BAD_REQUEST) code_record = VerifyCode(code=code, mobile=mobile) code_record.save() # 发送成功 return Response({ "mobile": sms_status["mobile"] }, status=status.HTTP_201_CREATED) -
create的源码

-
serializer–这里不用ModelSerializer是因为发送验证码时只需要提交一个手机号码过来, 而验证码表里面code又是必填字段, 所以说我们用ModelSerializer来做验证的话就会有一个问题, 你提交手机号码过来, code又是必填字段, 所以code会验证失败, 所以这里用Serializer自己写逻辑
import re from datetime import datetime from datetime import timedelta from rest_framework import serializers from django.contrib.auth import get_user_model # 正则表达式放在settings中 from MxShop.settings import REGEX_MOBILE from .models import VerifyCode # 获取用户模型类 UserProfile = get_user_model() class SmsSerializer(serializers.Serializer): # 获取序列化的字段 mobile = serializers.CharField(max_length=11) # 验证序列化的字段 # 验证的方法名必须是 validate_ + 要验证的字段名 def validate_mobile(self, mobile): """ 验证手机号码 :param mobile:手机号码 :return: """ # 校验手机号是否合法 if not re.match(REGEX_MOBILE, mobile): # 抛出异常 raise serializers.ValidationError("手机号码不合法") # 校验手机号是否被注册 if UserProfile.objects.filter(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): raise serializers.ValidationError("请60秒后重试, 谢谢") return mobile -
url
from rest_framework.routers import DefaultRouter from users.views import SmsCodeViewSet # 生成一个注册器实例对象 router = DefaultRouter() # 配置发送验证码url router.register(r'codes', SmsCodeViewSet, base_name="codes") urlpatterns = [ # 自动生成url url(r"^", include(router.urls)), ]
浙公网安备 33010602011771号