【发布时间】: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