检查函数是不是有装饰器

Posted

技术标签:

【中文标题】检查函数是不是有装饰器【英文标题】:Check if a function has a decorator检查函数是否有装饰器 【发布时间】:2011-07-26 06:26:58 【问题描述】:

我的问题很笼统,但具体来说,我的应用程序是 Django 的 login_required 装饰器。

我很好奇是否有办法检查视图/函数是否具有特定的装饰器(在本例中为 login_required 装饰器)

我在注销用户后重定向,如果他们当前所在的页面具有 login_required 装饰器,我想重定向到主页。到目前为止,我的搜索没有结果。

【问题讨论】:

【参考方案1】:

构建您自己的 login_required 装饰器并让它将函数标记为已装饰 - 可能最好的标记位置是在 func_dict

from django.contrib.auth.decorators import login_required as django_l_r

# Here you're defining your own decorator called `login_required`
# it uses Django's built in `login_required` decorator
def login_required(func):
    decorated_func = django_l_r(func)
    decorated_func.func_dict['login_is_required'] = True
    return decorated_func

@login_required # Your decorator
def authenticatedd_view(request):
    pass

def unauthenticated_view(request):
    pass

现在您可以检查视图是否被这样装饰...

# Assume `a_view` is view function
>>> a_view.func_dict.get('login_is_required',False)

如果您对 Python 装饰器感到困惑,请参阅这个 SO 问题/答案:How to make a chain of function decorators?

【讨论】:

"将函数标记为已装饰"?为什么不用正确的 URL 名称标记每个函数以在注销时重定向到?那会更直接有用。 @S.Lott 听起来您的意思是在视图函数中附加 URL 或 URL 名称,我认为这是不好的做法,因为它会混合您的 url 和视图,它们是在 Django 中明确分开。 @Chris W.:在视图中引用 URL 名称,以便 reverse() 可以工作。同样,在模板中引用 URL 名称,以便 % url % 可以工作。我不确定您所说的“混合”是什么意思。你能进一步解释一下吗? @S.Lott 现在你让我困惑了,reverse()% url % 的全部意义在于转换 view 函数(或视图的字符串描述符函数)到一个网址。这样一来,您的 html 模板和视图函数本身都不需要了解有关 URL 的任何信息。 @Chris W.: URL 可以有名字。 docs.djangoproject.com/en/1.3/topics/http/urls/…。这可以简化从许多视图函数中定位标准 URL 的过程。为注销提供标准 URL 名称通常非常非常方便。【参考方案2】:

看来你的情况如下: 1. 你的页面是安全的,并且在需要登录的装饰器后面 2. 您的页面不安全,可以在登录状态和匿名状态下访问。

如果我了解您的要求,您希望在用户注销时将用户重定向到主页(假设这是可以在登录和匿名状态下访问的欢迎页面)。

为什么不限制用户仅从安全页面注销,然后将注销时的 redirect_url 设置为欢迎屏幕?

【讨论】:

+1:这就是视图函数的用途。注销视图功能可以使用if request.user.is_anonymous()来确定是否注销某人,以及显示哪个页面。 是的,但是如果您尝试注销他们并将他们重定向回他们注销的页面,除非您知道该页面/视图是否受身份验证保护,否则这不起作用。

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

如何使用 Python 装饰器检查函数参数?

java 或 c# 中是不是有装饰器,例如 python functools 装饰器,即@wraps

python之“装饰器”

Typeorm 装饰器不是函数

NestJS 测试:装饰器不是函数

装饰器详解