注意:本文翻译自django1.8的官方文档
Permissions and Authorization
django提供了一个简单的权限管理系统.它提供方法给指定的用户和组分配权限
django的admin site使用了权限管理,然而你也可以你的代码中使用.
django的admit site使用了permissions以下功能:
- 用户浏览add表格和add对象,有add权限控制
- 用户浏览change表格和change对象,有change权限控制
- 用户删除对象,有删除权限控制
permissions不仅能用于每种对象,也能用于对象的实例.可以使用ModelAdmin类的has_add_permission(),has_change_permission(),has_delete_permission()方法来定给同一对象的不同实例来定制权限.
User对象有2个多对多字段:groups和user_permissions.User对象能像其他django模型一样来连接它的关联对象:
myuser.groups = [group_list]
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions = [permission_list]
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()
Default permissions
当INSTALL_APPS列表里有django.contrib.auth时,它会确保3个默认权限的存在:为你安装的app的模型创建add,change,delete权限
当你第一次运行manage.py migrate时,这些权限会被创建.以后再运行manage.py migrate时,只会会新添加的模型创建权限
假设你的应用有一个app_label叫foo,有一个模型叫Bar,你可以使用这些来测试基本权限:
- add: user.has_perm(‘foo.add_bar’)
- change: user.has_perm(‘foo.change_bar’)
- delete: user.has_perm(‘foo.delete_bar’)
很少直接访问Permission模型
Groups
django.contrib.auth.models.Group模型是一个通用的给用户分类的方法,这样你就能分配权限,或其他标签给用户.一个用户可以分配给任意一个或多个组.
用户能自动化获得所属组的权限.例如,如果组Site editors有can_edit_home_page权限,该组下面的用户就拥有这个权限.
除了权限,组还是一个方便的途径来给用户分类,给用户贴上标签,或者扩展功能.例如,你可以创建一个组叫’特殊用户’,并且写代码,给特殊用户访问会员专区的权限,或者发送会员专属邮件消息.
Programmatically creating permissions
除了在model的Meta class里定制权限,还可以直接创建权限.例如,你可以在myapp里给BlogPost模型创建can_publish权限:
from myapp.models import BlogPost
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(codename='can_publish',
name='Can Publish Posts',
content_type=content_type
)
通过User的user_permissions属性可以分配权限,或者通过Group的permissions属性
Permission caching
改变一个User对象的权限后,立即查看它的权限,会发现没有改变,这是因为有缓存.重新创建一个User对象,再查看权限,才能看到改变.例如:
from django.contrib.auth.models import Permisson, User
from django.shortcuts import get_object_or_404
def user_gains_perms(request, user_id):
user = get_object_or_404(User, pk=user_id)
# 任何权限检查都会缓存到当前的权限集合
user.has_perm('myapp.change_bar')
permission = Permission.objects.get(codename='change_bar')
user.user_permissions.add(permission)
# 检查缓存权限集合
user.has_perm('myapp.change_bar') # False
user = get_object_or_404(User, pk=user_id)
# 缓存权限重新从数据库里更新
user.has_perm('myapp.change_bar') # True