django - 在 Django 模板 : Check if user has permission to access view specified by name

标签 django django-templates django-authentication

假设我有一个用 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/

相关文章:

django - 在 nginx 上部署 django channel

Python:pickling locals(),或者 locals 有一个更轻量级的表兄弟吗?

python - 使用 args 的 get_absolute_url() 的 Django 模板不起作用

javascript - JS document.getElementById() 与 Int

python - Django 装饰器根据用户类型进行重定向

django - 如何在用户关闭基于 django2.0 的网站上的选项卡或浏览器时强制注销用户

Django webapplication 加载原生 TensorFlow 运行时失败。在 Heroku

python - "Add a related_name argument to the definition for ' XXX'.的自动解决方案?

Django auth.models.User 未经过身份验证,但存在于 auth 数据库中

django - 在没有 VirtualEnv 的情况下运行 Pinax