【问题标题】:Using a decorator with Django blocks the request在 Django 中使用装饰器会阻止请求
【发布时间】:2019-01-19 22:38:13
【问题描述】:

我正在尝试创建自己的装饰器,以便使用 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 模式。

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

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

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

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

【问题讨论】:

  • 如果my_api是基于函数的视图self,则不需要参数。不确定这是错误的原因,但尝试删除 self 参数。你能添加完整的回溯吗?
  • 你期望函数的调用顺序如何?这里它会先调用 allowed_states() 然后调用 action()。如果您的逻辑不同,请尝试更改顺序。
  • @neverwalkaloner - 我忘了提到我已经在没有 self 参数的情况下尝试过,但它不起作用。
  • @yogi - 在我发布问题之前尝试过这个。相同的行为:/
  • 如果 URL 路由在使用 @action 装饰器时通过处理处理函数的名称进行自动注册,则装饰器将无法工作,因为它不保留自省功能。你可以尝试使用functools.wraps,就像在你的装饰器实现中通常所做的那样,看看它是否有帮助。更好的是,使用像 wrapt 这样的装饰器库,它提供的装饰器比人们使用的典型模式更可靠。

标签: python django django-rest-framework python-decorators


【解决方案1】:

按照我使用 functools.wraps 的 cmets 中的建议解决了问题:

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

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 2020-12-12
    • 2017-10-13
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    • 2012-03-20
    相关资源
    最近更新 更多