Django - 权限分配、权限组件与CRM整合
一、权限分配
需求:为用户分配角色,为角色分配权限,如下图效果:

1、视图代码:
from django.shortcuts import render
from django.http import JsonResponse from rbac.models import User, Role, Permission def distribute_permissions(request):
"""
分配权限
"""
uid = request.GET.get('uid')
user = User.objects.filter(id=uid)
rid = request.GET.get('rid') # 保存为用户分配的角色
if request.method == 'POST' and request.POST.get('postType') == 'role':
r_lst = request.POST.getlist("roles")
user.first().roles.set(r_lst) # 保存为角色分配的权限
if request.method == 'POST' and request.POST.get('postType') == 'permission':
p_lst = request.POST.getlist("permissions_id")
Role.objects.filter(pk=rid).first().permissions.set(p_lst) user_list = User.objects.all()
role_list = Role.objects.all() if uid: # 选中某一用户,则显示其对应角色
role_id_list= User.objects.get(pk=uid).roles.all().values_list("pk")
role_id_list = [item[0] for item in role_id_list] if rid: # 点击某一角色,则显示其对应的权限
per_id_list = Role.objects.filter(pk=rid).values_list("permissions__pk").distinct()
else: # 不点击角色,则显示选中用户对应角色拥有的权限
per_id_list = User.objects.get(pk=uid).roles.values_list("permissions__pk").distinct()
per_id_list = [item[0] for item in per_id_list] return render(request, 'distribute_permission.html', locals()) # 显示权限表,ajax请求对应的视图函数
def permissions_tree(request):
permissions = Permission.objects.values("pk", "title", "url", "menu__title", "menu__pk", "pid_id")
return JsonResponse(list(permissions), safe=False)
注意:JsonResponse传入一个非字典类型的数据结构时,需要设置safe=False。
2、模板代码
1)显示用户表相关代码
<div class="am-panel-bd">
<ul class="user_ul">
{% for user in user_list %}
<li class={% if user.id|safe == uid %}"active"{% endif %}>
<a href="?uid={{ user.id }}">{{ user.name }}</a>
</li>
{% endfor %}
</ul>
</div>
2)显示角色表相关代码
<table class="am-table table-main mytable">
<thead>
<tr class="am-primary">
<th>角色</th>
<th>选择</th>
</tr>
</thead>
<tbody>
{% for role in role_list %}
<tr class={% if role.id|safe == rid %}"am-danger"{% endif %}>
{% load my_tags %}
<td>
<a href="?{% get_role_url request role.id %}">{{ role.title }}</a>
</td>
<td>
{% if role.id in role_id_list %}
<input type="checkbox" name="roles" value="{{ role.id }}" checked />
{% else %}
<input type="checkbox" name="roles" value="{{ role.id }}" />
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
3)显示权限表相关代码
<div class="am-panel-hd">
<span style="margin-left: 6px;">权限分配</span>
{% if rid %}
<button type="submit" class="am-btn am-fr"></i>保存</button>
{% endif %}
</div>
<p class="per_tips">提示:点击角色后才能为其分配权限</p>
<div class="am-panel-bd mypanel">
<table class="am-table table-main mytable">
<tbody id="tbd">
<!-- 通过文档加载时发送ajax请求获取用户权限,ajax代码如下 -->
</tbody>
</table>
</div> {% block js %}
<script>
$.ajax({
url:"/rbac/permissions_tree/",
type:"get",
success:function (res) {
console.log(res);
$.each(res, function (i, permission) { // 渲染权限树形结构
console.log(i, permission);
var menu_title = permission["menu__title"];
var menu_pk = permission["menu__pk"];
var url = permission["url"];
var parent_id = permission["pid_id"];
var pk = permission["pk"];
var title = permission["title"];
if (menu_title){ // 如果是菜单权限,即menu_id有值,pid_id为空
// 所属的一级菜单已经存在,则直接追加权限
if($("#menu_"+menu_pk).length){
var s = `
<tr id="per_${pk}">
<td class="">
<div class="">
<label>
<input name="permissions_id" value="${pk}" type="checkbox">
<span>${title}</span>
</label>
</div>
</td>
</tr>
`;
$("#menu_"+menu_pk).parent().append(s);
}else { // 所属的一级菜单不存在,即渲染菜单,又渲染权限
var s = `
<tr class="" id="menu_${menu_pk}">
<td>${menu_title}</td>
</tr>
<tr id="per_${pk}">
<td class="">
<div class="">
<label>
<input name="permissions_id" value="${pk}" type="checkbox">
<span>${title}</span>
</label>
</div>
</td>
</tr>
`;
$("#tbd").append(s);
}
}else { // 如果不是菜单权限,即menu_id为空,pid_id有值
var s = `
<div class="">
<label>
<input name="permissions_id" value="${pk}" type="checkbox">
<span>${title}</span>
</label>
</div>
`;
$("#per_"+parent_id+" td").append(s);
}
}); // 选中角色对应的权限
var per_id_list = {{ per_id_list }}
$.each(per_id_list, function (i, j) {
console.log($("[value='"+j+"']")[0]);
$("#tbd [value='"+j+"']").prop("checked", true);
}) }
})
</script>
{% endblock %}
3、思路分析
此需求难点是将权限表渲染在页面,有两种方案:在前端处理和在后端构建数据结构。
后端构建数据结构比较复杂,涉及到联动等。所以我们可以从前端入手,充分利用jquery的选择器,根据从数据库拿到的权限信息,用jquery技术渲染出来自己需要的结构。
二、将权限组件移植到CRM项目
(1) 先将rbac组件移植到新的项目中;
(2) 将settings中 INSTALLED_APPS 中加入"rbac";
(3) 将新项目的用户表与rbac下的User表一对一关联;
(4) 数据迁移;
(5) 在登录成功后引入rbac下的initial_session方法,做登录用户的权限信息存储(注意user对象);
(6) 在setting是中引入rbac下的权限校验中间件;
(7) 在项目的base模板中引入菜单样式,渲染显示;
Django - 权限分配、权限组件与CRM整合的更多相关文章
- python 全栈开发,Day107(CRM初始,权限组件之权限控制,权限系统表设计)
一.CRM初始 CRM,客户关系管理系统(Customer Relationship Management).企业用CRM技术来管理与客户之间的关系,以求提升企业成功的管理方式,其目的是协助企业管理销 ...
- django自定义rbac权限组件(二级菜单)
一.目录结构 二.表结构设计 model.py from django.db import models # Create your models here. class Menu(models.Mo ...
- Django项目:CRM(客户关系管理系统)--84--74PerfectCRM实现CRM权限和权限组限制访问URL
#models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...
- $Django Rest Framework-认证组件,权限组件 知识点回顾choices,on_delete
一 小知识点回顾 #orm class UserInfo (models.Model): id = models.AutoField (primary_key=True) name = models. ...
- 使用Mongodb+Shiro+SpringMVC实现动态权限分配
此次的文档只对Mongodb整合Shiro并且实现动态权限分配做整理,其它的内容以后会补上. 第一步.创建在web.xml中配置 Spring .Shiro shiroFilter 过滤器是用来将请求 ...
- rbac集成 权限分配。之角色管理
权限分配功能拆分: a. 角色管理 b. 用户管理 c. 菜单和权限的管理 d. 批量的权限操作 e. 分配权限 先实现 角色管理: 无非也就是,增删改查: 定义路由, 编写视图. 1.查看角色页面: ...
- 巨蟒django之权限6: 权限控制表设计&&登录权限
1.权限控制表设计 内容 . 什么是权限? . 为什么要有权限? 不同用户拥有不同的功能 . 在web开发中,什么是权限? url 代表 权限 . 开发一个权限的组件,为什么要开发组件? . 表结构的 ...
- Django实现Rbac权限管理
权限管理 权限管理是根据不同的用户有相应的权限功能,通常用到的权限管理理念Rbac. Rbac 基于角色的权限访问控制(Role-Based Access Control)作为传统访问控制(自主访问, ...
- 十二、基于Django实现RBAC权限管理
一.RBAC概述 RBAC(Role-Based Access Control,基于角色的访问控制),通过角色绑定权限,然后给用户划分角色. 从企业的角度来说,基本上是按照角色来划分职能.比如,CEO ...
随机推荐
- 从Python的角度来看编码与解码
导语: Python2和Python3中,因为默认字符集的不同而造成的麻烦,简直是程序员的梦魇!要彻底告别这个麻烦,就需要从本质上来理解编码和解码. 为什么要有编码? 对于不会英文的中国人来说,将英文 ...
- 李洪强iOS开发之iOS好文章收集
李洪强iOS开发之iOS好文章收集 该文收集朋友们转发或自己的写的技术文章,如果你也有相关的好文章,欢迎留言,当好文章多的时候,我会对这些好文章进行分门别类 文章 简述 日期 直播服务配置 使用 ng ...
- NiftyNet 项目了解
1. NiftyNet项目概述 NiftyNet项目对tensorflow进行了比较好的封装,实现了一整套的DeepLearning流程.将数据加载.模型加载,网络结构定义等进行了很好的分离,抽象封装 ...
- 文件IO之——阻塞和非阻塞及perror函数
读常规文件是不会阻塞的,不管读多少字节,read一定会在有限的时间内返回.从终端设备或网络读则不一定,如果从终端输入的数据没有换行符,调用read读终端设备就会阻塞,如果网络上没有接收到数据包,调用r ...
- SQLi-Labs学习笔记
结构化查询语言,也叫做SQL,从根本上说是一种处理数据库的编程语言.对于初学者,数据库仅仅是在客户端和服务端进行数据存储.SQL通过结构化查询,关系,面向对象编程等等来管理数据库.编程极客们总是搞出许 ...
- (译)Getting Started——1.2.1 Defining the Concept(确定理念)
每个出色的应用都是由理念开始的.在开发应用时,你不需要把理念完善和完成后再进行开发.但是你确实需要确定你要做什么,做完后的效果如何. 为了定义理念,问自己以下的问题: 应用的受众是哪些人?应用的内容和 ...
- Unity3D中简单的C#异步Socket实现
Unity3D中简单的C#异步Socket实现 简单的异步Socket实现..net框架自身提供了很完善的Socket底层.笔者在做Unity3D小东西的时候需要使用到Socket网络通信.于是决定自 ...
- android最佳实践的建议(翻译自android-best-practices)
Best practices in Android development Use Gradle and its recommended project structure 使用Gradle和其推荐的 ...
- Acme Corporation UVA - 11613 拆点法+最大费用最大流(费用取相反数)+费用有正负
/** 题目:Acme Corporation UVA - 11613 拆点法+最大费用最大流(费用取相反数)+费用有正负 链接:https://vjudge.net/problem/UVA-1161 ...
- java文件对话框操作
完毕文件打开与保存 FileDialog : FileDialog fd = new FileDialog(this); fd.setVisible(true);//或fd.show(); ...