视图函数已挂载permission_required装饰器但检测失败,如何正确检测?
正确检查视图是否挂载permission_required装饰器的方法
你的判断逻辑失效的原因是:Django的permission_required装饰器并没有用functools.partial实现,所以通过检查__wrapped__是否为functools.partial的方式根本匹配不到。
要正确检测,你需要沿着装饰器的包装链向上遍历,识别Djangopermission_required装饰器的特征,比如它内部的_permission_required函数标识,或者闭包中的关联参数。
具体实现代码
from django.http import HttpResponse from django.contrib.auth.decorators import permission_required from django.shortcuts import render def has_permission_required_decorator(view_func): current_func = view_func # 遍历装饰器包装链 while hasattr(current_func, '__wrapped__'): # 检查当前函数是否是Django内部的_permission_required装饰器函数 if current_func.__name__ == '_permission_required': return True # 或者通过闭包检查是否关联到permission_required装饰器 if hasattr(current_func, '__closure__'): for cell in current_func.__closure__: if cell.cell_contents == permission_required: return True current_func = current_func.__wrapped__ return False @permission_required() def my_home(request): from walterwhite.views import my_nav if has_permission_required_decorator(my_nav): print(f'{my_nav.__name__} has the @permission_required decorator') else: print(f'{my_nav.__name__} does not have the @permission_required decorator') return HttpResponse('In home') @permission_required() def my_nav(request): res = 'Hello this is the navigation bar' return render(request, 'index.html')
补充说明
- 如果你给
permission_required传了具体权限参数(比如@permission_required('auth.view_user')),还可以通过检查闭包中是否包含该权限字符串来进一步验证,确保是目标装饰器。 - 这种遍历
__wrapped__的方式是Python装饰器通用的检查方法,适用于大多数基于标准包装方式实现的装饰器。
内容的提问来源于stack exchange,提问作者Bharath
相关产品推荐
相关产品推荐

