后台
urls.py
path('sms/', views.SMSViewSet.as_view({'get': 'send'})),
throttles.py
from rest_framework.throttling import SimpleRateThrottle
from django.core.cache import cache
from django.conf import settings
# 结合手机验证码接口来书写
class SMSRateThrottle(SimpleRateThrottle):scope = 'sms'def get_cache_key(self, request, view):# 手机号是通过get请求提交的mobile = request.query_params.get('mobile', None)if not mobile:return None # 不限制# 手机验证码发送失败,不限制,只有发送成功才限制,如果需求是发送失败也做频率限制,就注释下方三行code = cache.get(settings.SMS_CACHE_KEY % {'mobile': mobile})if not code:return Nonereturn self.cache_format % {'scope': self.scope,'ident': mobile,}
const.py
# 短信验证码缓存key
SMS_CACHE_KEY = 'sms_cache_%(mobile)s'# 短信验证码缓存时间s
SMS_CACHE_TIME = 300
dev.py
REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'utils.exception.exception_handler','DEFAULT_THROTTLE_RATES': {'sms': '1/min'}
}
views.py
from libs import tx_sms
from django.core.cache import cache
from django.conf import settings
from .throttles import SMSRateThrottle
class SMSViewSet(ViewSet):# 设置频率限制,一个手机号一分钟只能访问一次throttle_classes = [SMSRateThrottle]def send(self, request, *args, **kwargs):# return APIResponse(result=False)# 1)接收前台手机号验证手机格式mobile = request.query_params.get('mobile', None)if not mobile:return APIResponse(1, 'mobile field required')if not re.match(r'^1[3-9][0-9]{9}$', mobile):return APIResponse(1, 'mobile field error')# 2)后台产生短信验证码code = tx_sms.get_code()# 3)把验证码交给第三方,发送短信result = tx_sms.send_code(mobile, code, settings.SMS_CACHE_TIME // 60)# 4)如果短信发送成功,服务器缓存验证码(内存数据库),方便下一次校验if result:cache.set(settings.SMS_CACHE_KEY % {'mobile': mobile}, code, settings.SMS_CACHE_TIME)# 5)响应前台短信是否发生成功return APIResponse(result=result)