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

3 投票
3 回答
2458 浏览
提问于 2025-04-18 08:00

我有一段代码,用来检查请求中是否包含了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有没有办法让我这样做?如果没有,我该如何自己用装饰器来实现呢?

3 个回答

-1

可以试试这个链接

不要用 require.POST(),可以改成 require.POST('email', 'password')

0

我来分享一下我的解决方案;

__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)
2

你需要一个自定义的装饰器,但可以把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 的源代码在这里。

撰写回答