背景
在写views
层的时候,需要做很多校验,判断请求类型,判断是否有必填项没传,而不同的请求类型,在代码中获取入参的方式也是不同的。
例如 get请求 xxx?a=1&b=2这种,使用 request.GET
,可以得到一个QueryDict
类型的对象,具备dict
同款的get
方法,可以通过request.GET.get('a')
的方法获取参数。
对于post
请求,xxx?a=1&b=2
这种也可以解析,使用request.POST
。
而对于包裹在body
下的json
格式入参数,就需要使用request.body
来获取,request.body
返回的是一个bytes类型,实际要使用还需要例如json.loads
进行转换。在这里又需要判断json.body
是否有值,需要判断json.loads
执行是否无异常,因为本身json
化就严格,经常不符合格式要求而报错。
以上在每个views
下方法来写一遍比较费力,参考了官方django.views.decorators.http
的内容,加入了类型判断和必传参数校验的逻辑,如果不满足预设内容,则将错误返回给前端,不往下执行业务代码。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
from functools import wraps from workflow.common.ResultUtils import ResultUtils import json
def request_verify(request_method: str, need_params=None): """ 在views方法上加装饰器 例如:@request_verify('get', ['id']) :param request_method: :param need_params: :return: """
def decorator(func): @wraps(func) def inner(request, *args, **kwargs): method = str(request.method).lower()
if request_method and not method == request_method.lower(): response = ResultUtils().django_jsonResponse_error(" method %s not allowed for: %s" % (request.method, request.path)) return response
request.params = {}
if method == 'get': if not request.GET: if need_params: response = ResultUtils().django_jsonResponse_error("缺少参数!") return response else: params = {} request_params = request.GET for item in request_params: params.update({item: request_params.get(item)}) request.params = params
else: if not request.body or request.body == {}: if need_params: response = ResultUtils().django_jsonResponse_error("缺少参数!") return response else: try: real_request_params = json.loads(request.body) except Exception as e: response = ResultUtils().django_jsonResponse_error("参数格式不合法!") return response
if need_params: for need_param_name in need_params: if not real_request_params.get(need_param_name): response = ResultUtils().django_jsonResponse_error(" 参数 %s 不能为空" % need_param_name) return response
request.params = real_request_params
return func(request, *args, **kwargs)
return inner
return decorator
|
用法
限制请求类型
get,post,大小写随意

当类型不合法,错误抛出
限制请求类型 + 必传参数

优先校验类型,类型校验通过校验必传参数,当必传参数缺失或值为空,错误抛出
错误示例(get请求传参已支持)
view层代码

请求类型与设定不符

请求为post但是body为空
request.params会得到一个空{}
请求为post且body有入参但与预设必传不符
请求为post且body有入参匹配预设必传,但参数值为空
