以下是如何解决您的问题的示例:
首先,创建一个装饰器包装器来代替permission_required:
from django.contrib.auth.decorators import login_required, permission_required, user_passes_test
from django.core.exceptions import PermissionDenied
from functools import wraps
from django.utils.decorators import available_attrs
def require_perms(*perms):
def decorator(view_func):
view_func.permissions = perms
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs):
for perm in perms:
return view_func(request, *args, **kwargs)
raise PermissionDenied()
return _wrapped_view
return decorator
然后,用它来装饰你的视图:
@require_perms('my_perm',)
def home(request):
.....
然后,为您的菜单项添加一个标签:
from django.core.urlresolvers import resolve
def check_menu_permissions(menu_path, user):
view = resolve(menu_path)
if hasattr(view.func, "permissions"):
permissions = view.func.permissions
for perm in permissions:
if user.has_perm(perm):
return True # Yep, the user can access this url
else:
return False # Nope, the user cannot access this url
return True # or False - depending on what is the default behavior
最后,在您的模板中,在构建菜单树时:
<button href="{{ some_path }} {% if not check_menu_permissions some_path request.user %}disabled="disabled"{% endif %} />
注意我没有用标签测试最后一部分,但我希望你明白了。这里的神奇之处在于在装饰器中为 view_func 添加权限,然后您可以使用 resolve(path) 访问它。我不确定这在性能方面的表现如何,但毕竟这只是一个想法。
编辑:刚刚修复了示例中的错误..