在Django中使用了rest_framework時,一般我們會定義ModelSerializer來校驗request.data中參數是否存在和參數類型。
但當我們只是想簡單校驗一些api的url上是否存在某些參數時,該怎么辦?當然我們也可以通過定義Serializer來實現,但很麻煩。
我們可以自定義請求參數驗證裝飾器來實現。類似如下(代碼不是完整的,只是示例):
from functools import wrapsfrom django.utils import six
from django.utils.decorators import available_attrsdef 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.GETif isinstance(param_names, six.string_types):params = (param_names,)else:params = param_namesfor param in params:if param not in request_params:return json_response_request_params_required(param)return view_func(request, *args, **kwargs)return _wrapped_viewreturn 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 = Truereturn view_func(*args, **kwargs)return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)