假设我有一个用 user_passes_test
装饰器装饰的 View :
# myapp/views.py
from django.views.generic import TemplateView
from django.contrib.auth.decorators import user_passes_test
def has_perm1_or_perm2(user):
return user.has_perm('myapp.perm1') or user.has_perm('myapp.perm2')
@user_passes_test(has_perm1_or_perm2)
class MyView(TemplateView):
# my view code goes here
然后我将它连接到一个 URL,如下所示:
# myapp/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
...,
url(r'^myview$', views.MyView.as_view(), name='myview'),
...
]
如果我想在模板中放置指向此 View 的链接,它看起来像这样:
<a href="{% url 'myapp:myview' %}">Check out my view!</a>
但我希望能够对模板进行一些控制,以便仅当当前登录的用户被为 View 指定的 user_passes_test
函数批准时才会显示上述内容.
即我想让我的模板看起来像这样:
{% if check_user_has_view_permission request.user 'myapp:myview' %}
<a href="{% url 'myapp:myview' %}">Check out my view!</a>
{% else %}
Nothing to see here...
{% endif %}
我怎样才能做到这一点?
谢谢!
最佳答案
你可以写一个custom template filter会这样做:
# myapp/templatetags/my_app_tags.py (probably need a better name...)
from django import template
from myapp.views import has_perm1_or_perm2
register = template.Library()
@register.filter
user_has_special_perms(user):
return has_perm1_or_perm2(user)
然后在你的模板中:
{% load my_app_tags %}
{% if request.user|user_has_special_perms %}
<a href="{% url 'myapp:myview' %}">Check out my view!</a>
{% else %}
Nothing to see here...
{% endif %}
或者你可以像这样直接检查个人权限:
{% if perms.myapp.perm1 and perms.myapp.perm2 %}
(显然这不那么干)。
编辑 - 如何让它更通用?
为了使它更通用,您可以这样做。首先创建某种 View 到权限的映射,例如:
# myapp/views.py
VIEW_PERMISSIONS = {
'MyView': has_perm1_or_perm2,
# etc for other views
}
然后像这样修改模板过滤器:
from myapp.views import VIEW_PERMISSIONS
@register.filter
user_has_special_perms(user, view_class):
perm_func = VIEW_PERMISSIONS.get(view_class, None)
if perm_func is not None:
return perm_func(user)
return false
然后在模板中:
{% if request.user|user_has_special_perms:"MyView" %}
我确信可以在不需要通过 VIEW_PERMISSIONS
进行显式映射的情况下实现这一点,对 View 类本身使用某种内省(introspection)。
关于django - 在 Django 模板 : Check if user has permission to access view specified by name,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36877690/