抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

背景

在写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
# -*- coding: utf-8 -*-
# @Author : 不言
# @Time : 2020/8/28 2:40 下午
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()

# 先判断类型,类型不符合,直接return
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 = {}

# 暂时不用get请求传参,get的情况可以先忽略
if method == 'get':
if not request.GET: # xxx.com或xxx.com/xx/?
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: # method == post
if not request.body or request.body == {}: # 参数为空的情况下
if need_params: # 验证必传
response = ResultUtils().django_jsonResponse_error("缺少参数!")
return response
else:
# 非空的时候,尝试去获取参数
try:
# 这边要try一下,如果前端传参不是json,json.loads会异常
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):
# 如果必传参数取出来是'' (PS: 没传和传了''通过get取出来都是''),就抛出
response = ResultUtils().django_jsonResponse_error(" 参数 %s 不能为空" % need_param_name)
return response

# 一直到这里都无异常那么就可以把参数塞进request对象了,避免view里还要再去json.loads
request.params = real_request_params

return func(request, *args, **kwargs)

return inner

return decorator

用法

限制请求类型

get,post,大小写随意

image.png

当类型不合法,错误抛出

限制请求类型 + 必传参数

image.png

优先校验类型,类型校验通过校验必传参数,当必传参数缺失或值为空,错误抛出

错误示例(get请求传参已支持)

view层代码

image.png

请求类型与设定不符

image.png

请求为post但是body为空

request.params会得到一个空{}

请求为post且body有入参但与预设必传不符

image.png

请求为post且body有入参匹配预设必传,但参数值为空

image.png

评论