假设我有一个用user_passes_test
装饰器装饰的视图:
# 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'),
...
]
如果我想在模板中放置此视图的链接,它将类似于:
<a href="{% url 'myapp:myview' %}">Check out my view!</a>
但是我希望能够对模板进行一些控制,以便仅在当前登录用户被视图指定的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 %}
我怎样才能实现这一目标?
谢谢!
答案 0 :(得分:1)
您可以编写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 %}
(显然这不太干)。
编辑 - 如何使其更通用?
为了使这更通用,你可以做这样的事情。首先创建某种视图到权限的映射,例如:
# 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
进行显式映射,在视图类本身上使用某种内省。