我创建了一个装饰器来检查一个人是否有会话,如下所示: (为简洁而添加评论)
def session_enabled(func=None, prefix='calling: '):
# some preprocessing
def session_enabled_wrapper(*args, **kwargs):
# check for session in request obj
# execute the function and get result onto a variable say result
# some API profiling logic
return result
return session_enabled_wrapper
我在一些观点上使用了这个:
@session_enabled
@csrf_exempt
def view_function(request):
# some processing
我的目标是检查是否在日志中没有此装饰器的情况下访问任何功能。 所以我写了一个中间件如下:
class SessionEnabledMiddleware(object):
'''
class that represents middleware called during requests
'''
def process_view(self, request, view_func, view_args, view_kwargs):
'''
called during the request cycle
:param request: request param
:param view_func: view function object
:param view_args: args passed to view function
:param view_kwargs: kwargs passed to view function
:return: None
'''
print('############# Inside session enabled middleware ###################')
if not view_func.__name__ == 'session_enabled_wrapper':
print('Function Not session enabled', request.path)
else:
print('function is session enabled', request.path)
我在settings.py文件中将上述中间件添加到MIDDLEWARE_CLASSES的元组中。 我很高兴,因为这有效,但幸福是短暂的,因为我的API开始崩溃403禁止错误。
经过一番研究,我改变了装饰器如下:
import functools
def session_enabled(func=None, prefix='calling: '):
# some preprocessing
@wraps(func)
def session_enabled_wrapper(*args, **kwargs):
# check for session in request obj
# execute the function and get result onto a variable say result
# some API profiling logic
return result
return session_enabled_wrapper
这意味着我早期的中间件逻辑失败了。我需要克服这一点。所以改变了我的中间件和装饰器,如下所示:
decorator:
def session_enabled(func=None, prefix='calling: '):
# some preprocessing
@wraps(func)
def wrapper(*args, **kwargs):
wrapper.session_enabled = True
# check for session in request obj
# actual function execution and get result onto a varible say result
# some API profiling logic
return result
wrapper.session_enabled = False
return wrapper
middleware:
class SessionEnabledMiddleware(object):
'''
class that represents middleware called during requests
'''
def process_view(self, request, view_func, view_args, view_kwargs):
'''
called during the request cycle
:param request: request param
:param view_func: view function object
:param view_args: args passed to view function
:param view_kwargs: kwargs passed to view function
:return: None
'''
print('############# Inside session enabled middleware ###################')
if not view_func.session_enabled:
print('Function Not session enabled', request.path)
else:
print('function is session enabled', request.path)
但我遇到了函数对象没有属性'session_enabled'。
我甚至尝试过:
view_function.__closure__[0].cell_contents.__name__
但是无法获得装饰者的名字。
我做错了什么?是否有任何可能的方法来获取装饰器的名称作为中间件中的条件或找到函数是否已装饰并采取必要的操作?
注意: Stackoverflow问题几乎满足上述要求: Detect Decorator in Python
修改
在考虑Vitor Freitas建议的链接后,我更改了代码如下:
@register(session_enabled, csrf_exempt)
def view_function(request):
# some processing
中间件:
class SessionEnabledMiddleware(object):
'''
class that represents middleware called during requests
'''
def process_view(self, request, view_func, view_args, view_kwargs):
'''
called during the request cycle
:param request: request param
:param view_func: view function object
:param view_args: args passed to view function
:param view_kwargs: kwargs passed to view function
:return: None
'''
try:
print('############# Inside session enabled middleware ###################')
decorators = [decorator.__name__ for decorator in view_func._decorators]
if 'session_enabled' in decorators:
print('Function is session enabled', request.path)
except:
print('function is not session enabled or decorated using register', request.path)
工作就像一个魅力......