基于角色的权限系统html
如今各大系统都采用的是基于角色的权限控制,这里就涉及到三个东西:用户、角色、资源(权限),在Django中就是:用户、用户组、权限。用户和角色的关系通常为多对多,角色和资源的关系也为多对多,以下图(此图来源于互联网)python
这样设计有一个好处,就是在系统愈来愈大的时候若是给每一个用户逐一赋予权限很是麻烦和繁琐,只须要给角色赋予相应的权限用户赋予他对应的角色便可,若是有新的需求只须要添加有相应权限的角色便可。django
Django权限机制的实现框架
一、不依赖于Django中的权限模型ui
设计三个实体类User、Role、Resource分别对应上面提出的用户、角色、资源,User和Resource之间为多对多的关系,Role和Resource之间为多对多的关系。User中封装的是用户的信息如用户名密码等,Resource能够封装权限标识(后面再进行分析)也能够封装容许访问的URL地址。spa
编写装饰器对视图处理方法进行拦截设计
在装饰器中获取当前访问的URL,取出当前用户(从Session中取,前题是在登陆的时候须要把用户信息放去Session中去),迭代判断用户的全部角色绑定的资源中的URL,若是存在与当前访问URL相同的地址则放行,不然则跳转到无权限的页面。code
弊端:若是URL发生了变更须要修改资源(权限)htm
在装饰器标示在视图处理方法上时传入权限标识参数(如:@auth("user:add")),在装饰器中也是从Session中获取用户,迭代用户的全部角色绑定的资源中的权限标识,若是与传入装饰器中的权限标识相同则放行,不然跳转到无权限的页面。继承
好处:若是URL发生了变更无需修改资源(权限),Django内部的权限系统就是采用的这种方式,Java目前愈来愈流行的权限控制框架Shiro也是采用的这种方式
二、依赖于Django中的权限模型(部分摘抄于:http://www.jianshu.com/p/01126437e8a4)
Django用User、Group、Permission来表示上面的用户、角色、资源(权限),在Django中无论你是否使用其自带的权限控制只要你继承了他的模型类(models.Model)会默认在auth_permission表中插入三个权限信息(以Book为例,会插入以下三个权限信息:add_book、change_book、delete_book,分别表明了添加、修改、删除三个权限),若是须要更多的权限信息能够在定义实体的时候以下定义:
class Book(models.Model): name = models.CharField() class Meta: permissions = ( ('自定义的权限标识', '权限说明信息'), )
每一个permission都是django.contrib.auth.Permission类型的实例,该类型包含三个字段name, codename 和 content_type,其中 content_type反应了permission属于哪一个model(如上就是Book),codename就是权限标识,代码逻辑中检查权限时要用, name是permission的描述显示的时候会用到。
权限检测装饰器:request.user封装了当前登陆系统的用户
from django.contrib.auth.decorators import permission_required @permission_required('应用名.权限标识') def view(request): ....
在模版中使用:模版中使用全局变量perms存储当前用户的全部权限
{% if perms.应用名.权限标识 %} <!-- 这里是有权限才显示的内容 --> {% endif %}