Django权限管理(permissions)与用户组(group)详解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Django权限管理(permissions)与⽤户组(group)详
解
如果你只是利⽤Django开发个博客,⼤部分⽤户只是阅读你的⽂章⽽已,你可能根本⽤不到本节内容。
但是如果你想开发⼀个内容管理系统,或⽤户管理系统,你必需对⽤户的权限进⾏管理和控制。
Django⾃带的权限机制(permissions)与⽤户组(group)可以让我们很⽅便地对⽤户权限进⾏管理。
⼩编我今天就尝试以浅显的语⾔来讲解下如何使⽤Django⾃带的权限管理机制。
什么是权限?
权限是能够约束⽤户⾏为和控制页⾯显⽰内容的⼀种机制。
⼀个完整的权限应该包含3个要素: ⽤户,对象和权限,即什么⽤户对什么对象有什么样的权限。
假设我们有⼀个应⽤叫blog,其包含⼀个叫Article(⽂章)的模型。
那么⼀个超级⽤户⼀般会有如下4种权限,⽽⼀个普通⽤户可能只有1种或某⼏种权限,⽐如只能查看⽂章,或者能查看和创建⽂章但是不能修改和删除。
查看⽂章(view)
创建⽂章(add)
更改⽂章(change)
删除⽂章(delete)
我们在Django的admin中是可以很轻易地给⽤户分配权限的。
Django Admin中的权限分配
Django中的⽤户权限分配,主要通过Django⾃带的Admin界⾯进⾏维护的。
当你编辑某个user信息时, 你可以很轻易地在User permissions栏为其设置对某些模型查看, 增加、更改和删除的权限(如下图所⽰)。
Django的权限permission本质是djang.contrib.auth中的⼀个模型, 其与User的user_permissions字段是多对多的关系。
当我们在INSTALLED_APP⾥添加好auth应⽤之后,Django就会为每⼀个你安装的app中的模型(Model)⾃动创建4个可选的权限:view, add,change和delete。
(注: Django 2.0前没有view权限)。
随后你可以通过admin将这些权限分配给不同⽤户。
查看⽤户的权限
权限名⼀般有app名(app_label),权限动作和模型名组成。
以blog应⽤为例,Django为Article模型⾃动创建的4个可选权限名分别为:
查看⽂章(view): blog.view_article
创建⽂章(add): blog.add_article
更改⽂章(change): blog.change_article
删除⽂章(delete): blog.delete_article
在前例中,我们已经通过Admin给⽤户A(user_A)分配了创建⽂章和修改⽂章的权限。
我们现在可以使⽤user.has_perm()⽅法来判断⽤户是否已经拥有相应权限。
下例中应该返回True。
user_A.has_perm('blog.add_article')
user_A.has_perm('blog.change_article')
如果我们要查看某个⽤户所在⽤户组的权限或某个⽤户的所有权限(包括从⽤户组获得的权限),我们可以使⽤
get_group_permissions()和get_all_permissions()⽅法。
user_A.get_group_permissions()
user_A.get_all_permissions()
⼿动定义和分配权限(Permissions
有时django创建的4种可选权限满⾜不了我们的要求,这时我们需要⾃定义权限。
实现⽅法主要有两种。
下⾯我们将分别使⽤2种⽅法给Article模型新增了两个权限,⼀个是publish_article, ⼀个是comment_article。
⽅法1. 在Model的meta属性中添加permissions。
class Article(models.Model):
...
class Meta:
permissions = (
("publish_article", "Can publish article"),
("comment_article", "Can comment article"),
)
⽅法2. 使⽤ContentType程序化创建permissions。
from blog.models import Article
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(article)
permission1 = Permission.objects.create(
codename='publish_article',
name='Can publish articles',
content_type=content_type,
)
permission2 = Permission.objects.create(
codename='comment_article',
name='Can comment articles',
content_type=content_type,
)
当你使⽤python manage.py migrate命令后,你会发现Django admin的user permissions栏⼜多了两个可选权限。
如果你不希望总是通过admin来给⽤户设置权限,你还可以在代码⾥⼿动给⽤户分配权限。
这⾥也有两种实现⽅法。
⽅法1. 使⽤er_permissions.add()⽅法
er_permissions.add(permission1, permission2, ...)
⽅法2. 通过user所在的⽤户组(group)给⽤户增加权限
mygroup.permissions.add(permission1, permission2, ...)
如果你希望在代码中移除⼀个⽤户的权限,你可以使⽤remove或clear⽅法。
er_permissions.remove(permission, permission, ...)
er_permissions.clear()
注意权限的缓存机制
Django会缓存每个⽤户对象,包括其权限user_permissions。
当你在代码中⼿动改变⼀个⽤户的权限后,你必须重新获取该⽤户对象,才能获取最新的权限。
⽐如下例在代码中给⽤户⼿动增加了change_blogpost的权限,如果不重新载⼊⽤户,那么将显⽰⽤户还是没有
change_blogpost的权限。
from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404
from myapp.models import BlogPost
def user_gains_perms(request, user_id):
user = get_object_or_404(User, pk=user_id)
# any permission check will cache the current set of permissions
user.has_perm('myapp.change_blogpost')
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.get(
codename='change_blogpost',
content_type=content_type,
)
er_permissions.add(permission)
# Checking the cached permission set
user.has_perm('myapp.change_blogpost') # False
# Request new instance of User
# Be aware that user.refresh_from_db() won't clear the cache.
user = get_object_or_404(User, pk=user_id)
# Permission cache is repopulated from the database
user.has_perm('myapp.change_blogpost') # True
⽤户权限的验证(Validation)
我们前⾯讲解了⽤户权限的创建和设置,现在我们将进⼊关键⼀环,⽤户权限的验证。
我们在分配好权限后,我们还需要在视图views.py和模板⾥验证⽤户是否具有相应的权限,否则前⾯设置的权限形同虚设。
这就是为什么我们前⾯很多django实战案例⾥,没有给⽤户分配某个模型的add和change权限,⽤户还是还能创建和编辑对象的原因。
1. 视图中验证
在视图中你当然可以使⽤user.has_perm⽅法对⼀个⽤户的权限进⾏直接验证。
当然⼀个更好的⽅法是使⽤
@permission_required这个装饰器。
permission_required(perm, login_url=None, raise_exception=False)
你如果指定了login_url, ⽤户会被要求先登录。
如果你设置了raise_exception=True, 会直接返回403⽆权限的错误,⽽不会跳转到登录页⾯。
使⽤⽅法如下所⽰:
from django.contrib.auth.decorators import permission_required
@permission_required('polls.can_vote')
def my_view(request):
...
如果你使⽤基于类的视图(Class Based View), ⽽不是函数视图,你需要继承PermissionRequiredMixin这个类,如下所⽰:
from django.contrib.auth.mixins import PermissionRequiredMixin
class MyView(PermissionRequiredMixin, View):
permission_required = 'polls.can_vote'
# Or multiple of permissions:
permission_required = ('polls.can_open', 'polls.can_edit')
2. 模板中验证
在模板中验证⽤户权限主要需要学会使⽤perms这个全局变量。
perms对当前⽤户的user.has_module_perms和
user.has_perm⽅法进⾏了封装。
当我们需要判断当前⽤户是否拥有blog应⽤下的所有权限时,我们可以使⽤:
{{ perms.blog }}
我们如果判断当前⽤户是否拥有blog应⽤下发表⽂章讨论的权限,则使⽤:
{{ ment_article }}
这样结合template的if标签,我们可以通过判断当前⽤户所具有的权限,显⽰不同的内容了.
{% if blog.article %}
<p>You have permission to do something in this blog app.</p>
{% if perms.blog.add_article %}
<p>You can add articles.</p>
{% endif %}
{% if ment_article %}
<p>You can comment articles!</p>
{% endif %}
{% else %}
<p>You don't have permission to do anything in the blog app.</p>
{% endif %}
⽤户组(Group)
⽤户组(Group)和User模型是多对多的关系。
其作⽤在权限控制时可以批量对⽤户的权限进⾏管理和分配,⽽不⽤⼀个⼀个⽤户分配,节省⼯作量。
将⼀个⽤户加⼊到⼀个Group中后,该⽤户就拥有了该Group所分配的所有权限。
例如,如果⼀个⽤户组editors有权限change_article, 那么所有属于editors组的⽤户都会有这个权限。
将⽤户添加到⽤户组或者给⽤户组(group)添加权限,⼀般建议直接通过django admin进⾏。
如果你希望⼿动给group添加或删除权限,你可以使⽤如下⽅法。
mygroup.permissions = [permission_list]
mygroup.permissions.add(permission, permission, ...)
mygroup.permissions.remove(permission, permission, ...)
mygroup.permissions.clear()
如果你要将某个⽤户移除某个⽤户组,可以使⽤如下⽅法。
myuser.groups.remove(group, group, ...) #
myuser.groups.clear()
Django⾃带权限机制的不⾜
Django⾃带的权限机制是针对模型的,这就意味着⼀个⽤户如果对Article模型有change的权限,那么该⽤户获得对所有⽂章对象进⾏修改的权限。
如果我们希望实现对单个⽂章对象的权限管理,我们需要借助于第三⽅库⽐如django guardian。
⾄于该库的使⽤,我们以后再详细介绍。
到此这篇关于Django 权限管理(permissions)与⽤户组(group)详解的⽂章就介绍到这了,更多相关Django 权限管理与⽤户组内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。