1.基于rbac的权限管理
RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间都是多对多的关系。
简单的模型图示如下:

2.Rbac组件的基本目录结构:

3.按照写的流程,来讲解rbac组件中的各个部分,以及功能,
3.1 models数据库表设计(models.py)。
为了在前端页面实现2方面的控制,还需要引入两个表菜单menu和分组group:1.在一个页面,当前用户的权限,例如是否显示添加按钮、编辑、删除等按钮;2.左侧菜单栏的创建。所以一共是5个类,7张表,详细model请看下边代码。
models.py
# models.py
from django.db import models
class Menu(models.Model):
'''页面中的菜单名'''
title = models.CharField(max_length=32)
class Group(models.Model):
'''权限url所属的组'''
caption = models.CharField(verbose_name='组名称',max_length=32)
menu =models.ForeignKey(verbose_name='组所属菜单',to='Menu',default=1) # 组所在的菜单
class Meta:
verbose_name_plural = 'Group组表'
def __str__(self):
return self.caption
class User(models.Model):
"""
用户表
"""
username = models.CharField(verbose_name='用户名',max_length=32)
password = models.CharField(verbose_name='密码',max_length=64)
email = models.CharField(verbose_name='邮箱',max_length=32)
roles = models.ManyToManyField(verbose_name='具有的所有角色',to="Role",blank=True)
class Meta:
verbose_name_plural = "用户表"
def __str__(self):
return self.username
class Role(models.Model):
"""
角色表
"""
title = models.CharField(max_length=32)
permissions = models.ManyToManyField(verbose_name='具有的所有权限',to='Permission',blank=True)
class Meta:
verbose_name_plural = "角色表"
def __str__(self):
return self.title
class Permission(models.Model):
"""
权限表
"""
title = models.CharField(verbose_name='标题',max_length=32)
url = models.CharField(verbose_name="含正则URL",max_length=64)
is_menu = models.BooleanField(verbose_name="是否是菜单")
code = models.CharField(verbose_name='url代码',max_length=32,default=0) # 路径对应的描述名称
group = models.ForeignKey(verbose_name='所属组',to='Group',null=True,blank=True) # 所属组
class Meta:
verbose_name_plural = "权限表"
def __str__(self):
return self.titlemodel
3.2 service中的init_permission.py
功能:在用户登录成功的时候,在session中写入两个内容:1.拿到当前用户的权限url(code信息);2.拿到当前用户的可以做菜单的url信息。
详细代码如下:
初始化权限
def init_permission(user, request):
'''
前端页面调用,把当前登录用户的权限放到session中,request参数指前端传入的当前当前login请求时的request
:param user: 当前登录用户
:param request: 当前请求
:return: None
'''
# 拿到当前用户的权限信息
permission_url_list = user.roles.values('permissions__group_id',
'permissions__code',
'permissions__url',
'permissions__group__menu__id', # 菜单需要
'permissions__group__menu__title', # 菜单需要
'permissions__title', # 菜单需要
'permissions__url', # 菜单需要
'permissions__is_menu', # 菜单需要
).distinct()
# 页面显示权限相关,用到了权限的分组,
dest_dic = {}
for each in permission_url_list:
if each['permissions__group_id'] in dest_dic:
dest_dic[each['permissions__group_id']]['code'].append(each['permissions__code'])
dest_dic[each['permissions__group_id']]['per_url'].append(each['permissions__url'])
else:
# 刚循环,先创建需要的结构,并把第一次的值放进去。
dest_dic[each['permissions__group_id']] = {'code': [each['permissions__code'], ],
'per_url': [each['permissions__url'], ]}
request.session['permission_url_list'] = dest_dic
# 页面菜单相关
# 1.去掉不做菜单的url,拿到的结果是menu_list,列表中的元素是字典
menu_list = []
for item_dic in permission_url_list:
if item_dic['permissions__is_menu']:
temp = {'menu_id':item_dic['permissions__group__menu__id'],
'menu_title':item_dic['permissions__group__menu__title'],
'permission__title': item_dic['permissions__title'],
'per@ child.permission__title }}</a></li>
{% endif %}
{% endfor %}
</ul>
{% endfor %}
</div>
使用inclusion_tag的文件示例:
inclusion_tag的使用模板文件
# 这个是django的模板文件
{% load rbac %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}模板{% endblock %}</title>
<link rel="stylesheet" href="{% static 'rbac/bootstrap-3.3.7/css/bootstrap.min.css' %}" rel="external nofollow" >
<link rel="stylesheet" href="{% static 'rbac/menu.css' %}" rel="external nofollow" >
{% block css %} {% endblock css %}
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-2 menu">
{% block menu %}
{% menu_html request %} {# 用inclusion_tag生成的menu_html #}
{% endblock menu %}
</div>
<div class="col-md-9">
{% block content %}
content
{% endblock %}
</div>
</div>
</div>
以上就是django中基于rbac实现的权限组件
这篇基于Django框架的权限组件rbac实例讲解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持社区。 |