使用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管理页面的用户编辑页面上授予权限。
检查用户是否具有特定权限
当调用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 %}