使用Django的Permission模型来限制视图访问权限

在Django中有一个叫做Permission的模型,创建Django的模型时会自动生成它。通过它,您可以限制只有拥有相应权限的用户才能在管理界面创建、更新、删除表格数据等。这次我们想利用这个Permission来限制View的操作。

創建獨立的權限

我将尝试创建一个新的权限数据,而不使用现有的权限数据。

指定ContentType

由于Permission模型需要将ContentType指定为外键,所以必须存在相应的ContentType。我认为,只需指定视图应用程序中所限制的ContentType即可,但也可以创建自定义的ContentType。

from django.contrib.contenttypes.models import ContentType


ContentType.objects.create(
    app_label='app_label', name='name', model='model')

在这里指定的app_label是应用程序的名称。也就是指定在settings的INSTALLED_APPS等地方的模块名称的末尾。

创建Permission数据

from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType


content_type = ContentType.objects.get(
    app_label='app_label', name='name', model='model')

Permission.objects.create(
    content_type_id=content_type.id, name='name', codename='codename')

name是表示权限的名称,例如’可以添加权限’,codename则是标识名称,例如’add_permission’。

给用户授予权限。

您可以从Django管理页面的用户编辑页面上授予权限。

perm.png

检查用户是否具有特定权限

当调用User实例的has_perm方法时,可以确认其是否具有特定的权限。需要传递的参数是’app_label.codename’的形式。例如,用户添加权限是’auth.add_user’。

from django.contrib.auth import get_user_model


User = get_user_model()
user = User.objects.get(pk=1)

user.has_perm('{app_label}.{codename}'.format(
    app_label='app_label', codename='codename'))

使用装饰器限制视图

(附注)

在Django中,如果要创建只有员工用户可以查看的视图,可以使用装饰器的方法。

from django.contrib.admin.views.decorators import staff_member_required
from django.utils.decorators import method_decorator
from django.views.generic.base import View


class SpamView(View):
    @method_decorator(staff_member_required)
    def dispatch(self, *args, **kwargs):
        return super(SpamView, self).dispatch(*args, **kwargs)

我会创建一个只有具有特定权限的用户才能看到的视图,仿照这个例子。

from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import user_passes_test


def get_permission_deco(permission_codename,
                        redirect_field_name=REDIRECT_FIELD_NAME,
                        login_url='admin:login'):
    def deco(view_func):
        return user_passes_test(
            lambda u: u.has_perm(permission_codename),
            login_url=login_url,
            redirect_field_name=redirect_field_name
        )(view_func)
    return deco

from django.utils.decorators import method_decorator
from django.views.generic.base import View

from .decorators import get_permission_deco


class EggView(View):
    @method_decorator(get_permission_deco('app_label.codename'))
    def dispatch(self, *args, **kwargs):
        return super(EggView, self).dispatch(*args, **kwargs)

(附言)

即使不用小技巧,Django也提供了一个名为”permission_required”的装饰器。
https://docs.djangoproject.com/ja/1.10/topics/auth/default/#the-permission-required-decorator

使用自定义标签限制模板

由于详细的自定义标签制作方法超出本文章的范围,因此省略不提。但是,我认为使用自定义标签来限制模板也是可能的,我将提供一个例子。

from django import template


register = template.Library()

@register.filter(name='has_perm')
def has_perm(user, permission_name):
    return user.has_perm(permission_name)

{% load perm_extra %}

{% if user|has_perm:'app_label.codename' %}
  <a href="/path">編集ページへ</a>
{% else %}
  <del>編集ページへ</del>(権限がありません)
{% endif %}
广告
将在 10 秒后关闭
bannerAds