Python 装饰器检查 Django 上的 POST 参数

Posted

技术标签:

【中文标题】Python 装饰器检查 Django 上的 POST 参数【英文标题】:Python decorator to check for POST parameters on Django 【发布时间】:2014-07-19 15:29:10 【问题描述】:

我有这样的代码来检查请求中是否包含 POST 参数:

def login(request):
    required_params = frozenset(('email', 'password'))
    if required_params <= frozenset(request.POST):
        # 'email' and 'password' are included in the POST request
        # continue as normal
        pass
    else:
        return HttpResponseBadRequest()

当所需的 POST 参数列表很大时,此代码会变得混乱。我想做的是:

@required_POST_params('email', 'password')
def login(request):
    # 'email' and 'password' are here always!
    pass

那么我确信 'email' 和 'password' POST 参数都包含在请求中,因为如果没有,请求将自动返回 HttpResponseBadRequest()

有没有 Django 允许我这样做的方法,如果没有,我怎么能自己用装饰器来做呢?

【问题讨论】:

【参考方案1】:

您需要一个自定义装饰器,但您可以将require_http_methods 作为基本示例:

def require_post_params(params):
    def decorator(func):
        @wraps(func, assigned=available_attrs(func))
        def inner(request, *args, **kwargs):
            if not all(param in request.POST for param in params):
                return HttpResponseBadRequest()
            return func(request, *args, **kwargs)
        return inner
    return decorator

示例用法:

@require_post_params(params=['email', 'password'])
def login(request):
    # 'email' and 'password' are here always!
    pass

仅供参考,require_http_methods source code。

【讨论】:

【参考方案2】:

我正在分享我的解决方案;

__author__ = 'yagmurs'
from copy import deepcopy
from rest_framework import status
from rest_framework.response import Response

def require_params(*params):
    def decorator(fn):
        def wrapped_function(request, *args, **kwargs):
            """
            Decorator for django rest service to meet both GET and POST request
            """
            error = deepcopy(REQUEST_INVALID_400)
            is_param_missing = False
            for param in params:
                if not get_param_from_request(param, request):
                    error['result_message'] += param + ", "
                    is_param_missing = True
            if is_param_missing:
                error['result_message'] = error['result_message'][:-2]
                return Response(error, status=status.HTTP_400_BAD_REQUEST)
            else:
                return fn(request, *args, **kwargs)
        return wrapped_function
    return decorator


def get_param_from_request(param, request):
    if request.method == 'POST':
        return request.data.get(param)
    else:
        return request.query_params.get(param)

【讨论】:

【参考方案3】:

试试this。

试试require.POST(),而不是require.POST('email', 'password')

【讨论】:

以上是关于Python 装饰器检查 Django 上的 POST 参数的主要内容,如果未能解决你的问题,请参考以下文章

Django中视图的多个装饰器:执行顺序

有啥方法可以获取具有装饰器、Python、Django 的视图名称列表

Python 装饰器和类方法和评估——django memoize

python Django装饰器(定时器,调试)

python Django自带的类装饰器

python使用装饰器@函数式化django开发