首页 > 解决方案 > 在 Django 中使用装饰器会阻止请求

问题描述

我正在尝试创建自己的装饰器,以便使用 Django 验证 REST 调用(使用 Django Rest Framework)。

装饰器看起来像这样:

def allowed_states(allowed=[]):
    def decorator(func):
        def wrapper(self, request, *args, **kwargs):
            print(func)
            result = func(self, request, *args, **kwargs)
            return result
        return wrapper
    return decorator

请求 API 如下所示:

@swagger_auto_schema(
    operation_id="my_api",
    responses={
        status.HTTP_204_NO_CONTENT: "",
    }
)
@action(detail=True, methods=["DELETE"])
@allowed_states(allowed=["state1", "state2"])
def my_api(self, request, *args, **kwargs):
    # do some stuff here

当我的@allowed_states装饰器被移除时,调用工作正常。当我将它添加回来时,我从 Django 框架收到 404 错误,说它找不到要为此调用执行的 url 模式。

我尝试selfwrapper(以及从func调用中删除)。我还尝试更改函数调用上方的装饰器顺序。两者都没有工作。

堆栈跟踪并没有说太多,只是 django 找不到 url 模式:

 Using the URLconf defined in 
                <code>my_project.urls</code>,
      Django tried these URL patterns, in this order:

(然后是 url 模式出现的顺序my_project.urls

标签: pythondjangodjango-rest-frameworkpython-decorators

解决方案


遵循我使用的评论中的建议functools.wraps并解决了问题:

from functools import wraps

def allowed_states(allowed=[]):
    def decorator(func):
        @wraps(func)
        def wrapper(self, request, *args, **kwargs):
            print(func)
            result = func(self, request, *args, **kwargs)
            return result
        return wrapper
    return decorator

推荐阅读