1.rbac-优化login函数  

  因为login是业务逻辑 ,而rbac是个组件 ,将rbac在login的代码分离

###初始化权限函数分离出去 rbac/service/permission
from untitled import settings def init_permission(request, obj):
permission_query = obj.roles.all().filter(permissions__url__isnull=False).values(
'permissions__title',
'permissions__url',
'permissions__is_menu',
'permissions__name',
).distinct() permission_dict = {}
menu_list = [] for i in permission_query:
permission_dict[i['permissions__name']] = {'url': i['permissions__url']}
if i['permissions__is_menu']:
menu_list.append({'title': i['permissions__title'], 'url': i['permissions__url']}) # 将对象列表转换为列表 ! 并将用户权限存入session
request.session[settings.PERMISSION_SESSION_KEY] = permission_dict
request.session[settings.MENU_SESSION_KEY] = menu_list
# 此刻该用户登录成功
request.session['is_login'] = True ###login函数直接使用
class login(View):
def get(self, request):
return render(request, 'login.html') def post(self, request):
name = request.POST.get('username')
password = request.POST.get('password')
md5 = hashlib.md5()
md5.update(password.encode('utf-8'))
md5_pwd = md5.hexdigest()
print(md5_pwd, name)
obj = models.User.objects.filter(name=name, password=md5_pwd).first()
if not obj:
return HttpResponse('账号密码错误')
# 初始化用户权限
else:
init_permission(request, obj)
return redirect(reverse('crm:deplist'))

2.业务-保留搜索条件

  问题: 在第9页修改了某条数据提交后 ,直接跳到了第1页 ,这是因为视图函数返回到了展示页面没有携带页码

  解决方法:  1.点击修改后的页面url要有上个页面的页码(前端)  2.点击提交数据跳转的页面携带当前页面的页码(view函数)

  思想: 关注request,确保每次访问的url都有页码参数 ,因为request每次请求都会变化,所以每次都要加参数

    定义simple_tag函数返回增加了page参数的url ,前端a标签调用函数获得url

       request.GET.urlencode()     是当前url上的参数

###/rbac/middlewares/my_define
@register.simple_tag
def reverse_url(request, *args, **kwargs):
# get的参数
params = request.GET.urlencode()
# 跳转的url args[0]是url别名 args[1]是url别名参数
url = reverse(args[0], args=(args[1],)) return '{}?{}'.format(url, params) ###前端html中 执行函数
{% if request|has_permission:'dep_edit' %}
<td>
<a href={% reverse_url request 'crm:depedit' obj.pk %}><i class="fa fa-pencil-square-o"
aria-hidden="true">&nbsp&nbsp&nbsp</i></a>
<a class="b1" del_id="{{ obj.pk }}" style="color: red"><i class=" fa fa-remove"
aria-hidden="true"></i></a></td>
{% endif %}

    修改视图函数中的redirect的值 ,直接拼接上url的参数

      url_name定义为原来reverse的无参数的url

##通用工具utils/reverse_url
from django.urls import reverse def reverse_url(request, url_name, *args, **kwargs):
url = reverse(url_name)
params = request.GET.urlencode()
return '{}?{}'.format(url, params) ##跳转页面修改视图函数dep.py
def depadd(request):
....
return redirect(reverse('crm:deplist'))
...

3.权限二级菜单

  一级菜单为信息管理

    二级菜单为班级列表与部门列表

  一级菜单为用户管理

    二级菜单为用户列表

  思路: 如果要完成二级菜单 ,我们需要以一级菜单为主导 ,子信息包含二级菜单所有信息 ,根据这个想法我们将取出的权限信息进行分析

  1) 完成models的设计

    新增Menu表用来存储一级菜单 ,和一级菜单的其他信息(样式什么的)

class Menu(models.Model):
title = models.CharField('菜单名称', max_length=32)
icon = models.CharField('样式', max_length=128) def __str__(self):
return self.title

    修改Permission表中的is_menu的字段 ,将该字段直接删除 ,信增外键关联Menu表 ,此时所有关联Menu表的权限都是二级菜单

class Permisssion(models.Model):
url = models.CharField('含正则url', max_length=128)
title = models.CharField('中文权限标题', max_length=32, blank=True, null=True)
name = models.CharField('url的别名', max_length=32, unique=True)
# is_menu = models.BooleanField('是否为菜单', default=False)
menu = models.ForeignKey('Menu', blank=True, null=True) def __str__(self):
return self.title

    修改admin中原来的is_menu消失的字段 ,做数据迁移

  2)新增一级菜单数据  --> 并将权限关联一级菜单

    名称:信息管理   样式:fa-eercast

    名称:用户管理   样式:fa-address-book

  3)重新从权限中获取的管家数据permission_query

    通过角色表的权限外键获取 : 权限的名字  权限的标题  权限的url  权限的外键id是否为空

    通过角色表的权限外键获取到权限表的Menu外键 : 一级菜单的标题  一级菜单的样式

##原来数据格式
permission_query = obj.roles.all().filter(permissions__url__isnull=False).values(
'permissions__name',
'permissions__title',
'permissions__url',
'permissions__menu_id',
'permissions__menu__title',
'permissions__menu__icon', ).distinct() # 对列表中重复的字典进行去重

##生成菜单字典的1示例格式 :一级菜单收缩下拉框, 二级菜单作为子值负责跳转url
menu_id:{
menu_title: 信息管理,
menu_icon: fa-eercast,
children: [
{ permissions__title: '班级列表' ,url:'/crm/class/list' },
{ permissions__title: '部门管理' ,url:'/crm/dep/list' }
]
}
from untitled import settings

def init_permission(request, obj):
# permission_query是该用户的所有权限 ,从角色表出发 ,根据外键的权限表打印出所有的所需要信息
permission_query = obj.roles.all().filter(permissions__url__isnull=False).values(
'permissions__name',
'permissions__title',
'permissions__url',
'permissions__menu_id',
'permissions__menu__title',
'permissions__menu__icon', ).distinct() # 对列表中重复的字典进行去重 permission_dict = {}
menu_dict = {} for i in permission_query:
# 生成权限字典
permission_dict[i['permissions__name']] = {'url': i['permissions__url']} # 生成一级菜单字典
if i['permissions__menu_id'] not in menu_dict:
menu_dict['permissions__menu_id'] = {
'title': i['permissions__menu__title'],
'icon': i['pemissions__menu__icon'],
'children': [
{'title': i['permissions__url'], 'url': i['permissions__url']}
]
}
# 如果字典中有一级菜单的key就可以直接追加一个children了
else:
menu_dict['permissions__menu_id']['children'].append(
{'title': i['permissions__url'], 'url': i['permissions__url']}) # 将对象列表转换为列表 ! 并将用户权限存入session
request.session[settings.PERMISSION_SESSION_KEY] = permission_dict
request.session[settings.MENU_SESSION_KEY] = menu_dict
# 此刻该用户登录成功
request.session['is_login'] = True

  4) inclusion_tag修改支持一级菜单二级菜单显示 ,并新增权重排序字典 ,和非菜单归属(需要新增weight字段与parent字段 )

@register.inclusion_tag('menu.html')
def menu(request):
"""拿出当前url
给所有的一级菜单都hide隐藏
再循环二级菜单 ,如果当前地址匹配到了二级菜单 ,给二级标签重点标记active ,并把一级菜单取出hide
修改后的菜单字典传给前端
""" # 这个url是当前访问的url
url = request.path_info
menu_dict = request.session[settings.MENU_SESSION_KEY]
permissions_dict = request.session[settings.PERMISSION_SESSION_KEY] # 非菜单权限归属重新定义url解决
for i in permissions_dict.values():
if re.match('^{}$'.format(i['url']), url) and i['parent']:
# 这里将url直接替换为费权限归属的parent__url ,因为该url就是用来生成菜单的
url = i['parent']
break # 根据权重将menu_dict变为有序字典
sort_dict = OrderedDict()
temp_lst = sorted(menu_dict, key=lambda x: menu_dict[x]['weight'], reverse=True)
for i in temp_lst:
sort_dict[i] = menu_dict[i] for i in sort_dict.values(): # 开始获取将全部的隐藏 ,仅将匹配到的url取消隐藏
i['class'] = 'hide'
for child in i['children']:
if re.match('^{}$'.format(child['url']), url):
child['class'] = 'active'
i['class'] = ''
return {'menu_dict': sort_dict.values()}
 

    

4.面包屑功能

  1)拿到对应的数据放入权限字典

        permission_dict[i['permissions__name']] = {'url': i['permissions__url'],
'title': i['permissions__title'],
'parent': i['permissions__parent__url'],
'parent_title': i['permissions__parent__title']}

  2)inclusion_tags中定义数据结构 ,将一级菜单和非权限菜单分离 ,放入breadcrum_list列表中

@register.inclusion_tag('breadcrumb.html')
def breadcrum(request):
url = request.path_info
permission_dict = request.session[settings.PERMISSION_SESSION_KEY]
# 导航数据
breadcrum_list = [{'title': '首页', 'url': '/crm/dep/list/', }] for i in permission_dict.values(): # 二级菜单
if re.match('^{}$'.format(i['url']), url) and not i['parent']:
breadcrum_list.append({'title': i['title'],
'url': i['url'], })
break
# 非权限菜单
if re.match('^{}$'.format(i['url']), url) and i['parent']:
breadcrum_list.append({'title': i['parent_title'], 'url': i['parent'], })
breadcrum_list.append({'title': i['title'], 'url': i['url'], })
break return {'breadcrum_list': breadcrum_list}

  3)html中展示 ,如果是最后一个不用a标签  ,layout模板引用

####breadcrumb.html
<ol class="breadcrumb">

    {% for breadcrum in breadcrum_list %}
{% if forloop.last %}
<li>{{ breadcrum.title }}</li>
{% else %}
<li><a href="{{ breadcrum.url }}">{{ breadcrum.title }}</a></li>
{% endif %}
{% endfor %} </ol> ###layout.html
<div class="right-body">
<div>
{% breadcrum request %}
</div>
....

  

5.使用redis存储session

  1)搭建redis

    docker pull redis

    docker run -p 6379:6379 -v /redis:/data -d redis  --appendonly yes

    docker exec -it 容器ID redis-cli -h 192.168.1.30 -p  6379

  2)django配置

    pip install django-redis-sessions==0.5.6

    settings.py配置  

SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = '192.168.1.30'
SESSION_REDIS_PORT =
SESSION_REDIS_DB = 1            #指定存到redis的一个库中,默配置16个库
SESSION_REDIS_PASSWORD = ''
SESSION_REDIS_PREFIX = 'session'

  3)验证

    docker exec -it 容器ID redis-cli -h 192.168.1.30 -p  6379

    select 1       #切库 

    keys *        #看到session

    flushdb        #清空后web端退出登录


  

crm-4权限的更多相关文章

  1. Dynamics CRM 2011 权限管理(转)

    http://www.cnblogs.com/LeoTang/p/3344265.html Dynamics CRM 2011 权限管理 CRM系统基于角色的权限主要通过部门.角色.用户.团队来 进行 ...

  2. Django项目:CRM(客户关系管理系统)--85--75PerfectCRM实现CRM扩展权限

    # sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...

  3. crm操作权限

    using System;     using Microsoft.Xrm.Sdk;     using Microsoft.Xrm.Sdk.Query;     using System.Colle ...

  4. python 全栈开发,Day107(CRM初始,权限组件之权限控制,权限系统表设计)

    一.CRM初始 CRM,客户关系管理系统(Customer Relationship Management).企业用CRM技术来管理与客户之间的关系,以求提升企业成功的管理方式,其目的是协助企业管理销 ...

  5. Dynamics CRM 2011 权限管理

    CRM系统基于角色的权限主要通过部门.角色.用户.团队来进行控制.每一个实体记录的所有者(Owner)必然是某一个用户或团队.一个用户或团队必然归属于一个且只归属于一个部门,但团队的成员即用户可以来自 ...

  6. day28 CRM万能权限组件开发 && 主机管理-堡垒机

    1,CRM项目实战-万能权限组件开发参考博客:http://www.cnblogs.com/alex3714/articles/6661911.html 参考代码:https://github.com ...

  7. day 71 crm(8) 权限组件的设置,以及权限组件的应用

    ---恢复内容开始--- 前情提要: strak 组件是增删改查组件 , 生活中,需求权限组件,  不足: 1,前后端不分离,   2, 空url也会刷新界面,造成资源浪费   3,如果角色忘记设置权 ...

  8. crm项目-权限组件

    ###############    表结构分析     ################ """ 表结构设计: 1,四张表 用户表,userinfo,这个表本身不会被创 ...

  9. Dynamics CRM 权限整理二

    接上篇http://blog.csdn.net/vic0228/article/details/50510605,继续列举CRM相关权限 prvReadBusinessUnit privilege(I ...

  10. CRM项目之RBAC权限组件-day26

    写在前面 上课第26天,打卡: 世间安得双全法 不负如来不负卿 s17day26 CRM项目 项目概要:XX公司CRM - 权限管理,公共组件,app ***** - 熟悉增删改查,Low *** - ...

随机推荐

  1. 【数据结构】什么是二叉查找树(BST)

    什么是二叉查找树(BST) 1. 什么是BST 对于二叉树中的每个节点X,它的左子树中所有项的值都小于X中的项,它的右子树中所有项的值大于X中的项.这样的二叉树是二叉查找树. 以上是一颗二叉查找树,其 ...

  2. Vue 从入门到进阶之路(十二)

    之前的文章我们介绍了一下 vue 中插槽的使用,本章我们接着介绍一下 vue 中的作用域插槽. <!DOCTYPE html> <html lang="en"&g ...

  3. MFC图形编辑界面工具

    一.背景 喔,五天的实训终于结束了,学校安排的这次实训课名称叫高级程序设计实训,但在我看来,主要是学习了Visual C++ .NET所提供的MFC(Microsoft Foundation Clas ...

  4. ABAP - AT END OF 的使用

    TYPES: begin of ty_tab , num() type i, str() type c, end of ty_tab. data: gw_tab TYPE ty_tab , gt_ta ...

  5. jvm虚拟机笔记<一> 内存区域

    运行时数据区域: 程序计数器:字节码的行号指示器. 虚拟机栈:为每个方法创建一个栈帧(存放方法中的局部变量,变量引用等). 本地方法栈:存放本地方法. ------------------------ ...

  6. IDEA中安装EasyCode插件并连接数据库生成代码

    场景 EasyCode是基于IntelliJ IDEA开发的代码生成插件,支持自定义任意模板(Java,html,js,xml).只要是与数据库相关的代码都可以通过自定义模板来生成.支持数据库类型与j ...

  7. 松软科技前端课堂:JavaScript 数值方法

    Number 方法帮助您处理数值. Number 方法和属性 原始值(比如 3.14 或 2016),无法拥有属性和方法(因为它们不是对象). 但是通过 JavaScript,方法和属性也可用于原始值 ...

  8. 下载EPM包详细运行日志

    事务码:UJFS,选择包运行的环境名称. 从root根目录下进入对应环境->模型目录,找到privatepublications 文件夹对应的账号文件夹(运行包的账号名称) 进入tempfile ...

  9. Jackson version is too old 2.xx

    我使用的是IDEA,很简单. 切换到project,如果下面的module版本是2.65,上面的jackson.core.xx小于2.65就会报old,如果高于2.65就会报不兼容. 所以调整成相同的 ...

  10. 微信小程序根据生日获取年龄

    // 根据出生日期计算年龄周岁 传参格式为1996-06-08 // 根据出生日期计算年龄周岁 传参格式为1996-06-08 function getAge(strBirthday) { var r ...