首先是视图函数view的代码
class SmsCodeView(GenericAPIView):
# parser_classes = [JSONParser, FormParser] # 改成接受表单
serializer_class = serializers.ImageCodeCheckSerializer
def post(self, request):
# 获取数据(image_code_id,text)mobile参数不用校验,因为是通过正则匹配路由,匹配不成功就不会进入到路由,所以不用验证mobile
# 校验数据(通过image_code_id查询redis),由序列化器完成
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
mobile = request.data.get('mobile')
# 生成验证码内容
sms_code = '%d' % random.randint(100000, 999999)
# 保存短信验证码与发送记录
redis_conn = get_redis_connection('verify_codes')
# 调用自己写的阿里云短信服务发送短信
try:
# send_sms = AliyunSms(settings.ACCESSKEYID, settings.ACCESSSECRET, settings.SIGNNAME)
# result_code = send_sms.send_sms(mobile, sms_code, constants.SMS_CODE_TEMP_ID)
result_code = 'OK'
# 使用redis管道
pl = redis_conn.pipeline()
pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code) # 设置短信验证码内容redis记录
pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1) # 设置短信验证码发送记录
pl.execute()
except Exception as e:
sms_logger.error("发送短信验证码[异常][mobile:%s, message:%s]" % (mobile, e))
return gen_response('发送短信验证码异常', status=1, response_status=500)
else:
if result_code == 'OK':
sms_logger.info("发送短信验证码[正常][mobile:%s]" % mobile)
return gen_response('短信验证码发送成功,手机号{},验证码{}'.format(mobile, sms_code))
# return Response({'message': '手机号{},验证码{}'.format(mobile, sms_code)})
elif result_code == 'isv.DAY_LIMIT_CONTROL':
sms_logger.warning("发送短信验证码[失败][触发日发送限额][mobile:%s]" % mobile)
return gen_response('您今天获取的短信验证码已达最大限额', status=1, response_status=400)
elif result_code == 'isv.BUSINESS_LIMIT_CONTROL':
sms_logger.warning("发送短信验证码[失败][触发日发送限额][mobile:%s]" % mobile)
return gen_response('您今天获取的短信验证码已达最大限额', status=1, response_status=400)
else:
sms_logger.warning("发送短信验证码[失败][触发日发送限额][mobile:%s]" % mobile)
return gen_response('您今天获取的短信验证码已达最大限额', status=1, response_status=400)
然后是serializer的代码
class ImageCodeCheckSerializer(serializers.Serializer):
"""
图片验证码校验序列化器
"""
image_code_id = serializers.UUIDField()
text = serializers.CharField(max_length=4, min_length=4)
mobile = serializers.CharField(max_length=11, min_length=11)
def validate(self, attrs):
# 从attrs字典里获取相应的数据
image_code_id = attrs['image_code_id']
text = attrs['text']
mobile = attrs['mobile']
# 判断手机号
if not re.match(r'^1[3-9]\d{9}$', mobile):
# return gen_response('手机号格式错误', status=1)
raise serializers.ValidationError(detail={'status': 1, 'message': '手机号格式错误', 'data': None})
# 查询真实图片验证码
redis_conn = get_redis_connection('verify_codes')
real_text_image_code = redis_conn.get('img_{}'.format(image_code_id))
if not real_text_image_code:
# return gen_response('图片验证码无效', status=1)
raise serializers.ValidationError(detail={'status': 1, 'message': '图片验证码无效', 'data': None})
# 删除图片验证码
try:
redis_conn.delete('img_%s' % image_code_id)
except RedisError as e:
logger.error(e)
# 对比校验
real_text_image_code = real_text_image_code.decode()
if real_text_image_code.lower() != text.lower():
# return gen_response('图片验证码无效', status=1)
raise serializers.ValidationError(detail={'status': 1, 'message': '图片验证码无效', 'data': None})
# 判断是否在60s内发送过
send_flag = redis_conn.get('send_flag_%s' % mobile)
# 如果send_flag 有值.那么说明已经发送过.那就抛出错误
if send_flag:
# return gen_response('请求过于频繁', status=1)
raise serializers.ValidationError(detail={"status": 1, "message": "请求过于频繁", "data": None})
return attrs
我是想让raise serializers.ValidationError返回的是我自己定义的这种形式的json
{
"status": 1,
"message": "图片验证码无效",
"data": null
}
但是我请求返回的却是这样的
{
"status": [
"1"
],
"message": [
"图片验证码无效"
],
"data": [
"None"
]
}
每个键对应的值变成了列表。
想问下怎么才能返回自定义的json
需要重写Field
在restframework.fields.py中224有一段转换错误提示的函数。