在Django中使用了rest_framework时,一般我们会定义ModelSerializer来校验request.data中参数是否存在和参数类型。
但当我们只是想简单校验一些api的url上是否存在某些参数时,该怎么办?当然我们也可以通过定义Serializer来实现,但很麻烦。
我们可以自定义请求参数验证装饰器来实现。类似如下(代码不是完整的,只是示例):
from functools import wraps
from django.utils import six
from django.utils.decorators import available_attrs
def request_params_required(param_names, raise_exception=False):
"""
验证request的URL中必须的参数
:param param_names:
:param raise_exception:
:return:
"""
def decorator(view_func):
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs):
request_params = request.GET
if isinstance(param_names, six.string_types):
params = (param_names,)
else:
params = param_names
for param in params:
if param not in request_params:
return json_response_request_params_required(param)
return view_func(request, *args, **kwargs)
return _wrapped_view
return decorator
以上代码中使用@wraps(view_func, assigned=available_attrs(view_func))的目的是保留原始函数的身份信息。
在需要验证url参数的api上就可以使用上面的请求参数验证装饰器(代码不是完整的,只是示例:
@api_view(['GET'])
@request_params_required('redirect_uri')
def gitlab_login_oauth_uri(request):
redirect_uri = request.GET.get('redirect_uri')
if not redirect_uri:
return api_request_params_required("redirect_uri")
client = GitlabOauthClient()
oauth_url = client.get_oauth_url(redirect_uri)
return api_success({'oauth_url': oauth_url})
@api_view(['GET'])
@request_params_required(['page', 'page_size'])
def all_report_list(request):
data = []
"""
省略业务逻辑
"""
return api_success(data)
上面的装饰器,需要传递格外参数,所以必须是三层。不需要传递参数的装饰器两层就够了。如下一个跳过CSRF验证的装饰器。
def csrf_ignore(view_func):
"""
Skips the CSRF checks by setting the 'csrf_processing_done' to true.
"""
def wrapped_view(request, *args, **kwargs):
request.csrf_processing_done = True
return view_func(*args, **kwargs)
return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)