当用户登陆后,根据用户的角色要为用户生成对应的权限菜单,此时需要将登陆的用户信息获取且获取角色信息,从数据库中获取菜单以及权限信息,并且存入session中。

1、权限流程

第一次请求的页面是登陆页面,已经被列入白名单,根据登陆的用户信息,获取用户的角色信息,从而拿到一个或者多个角色的权限、菜单信息,并且将其保存在session中,当用户第二次发起请求时,通过权限校验(通过之前保存在session中的信息,利用中间件进行校验),获取用户的菜单和权限信息,这样就完成了用户权限的设置。

2、权限初始化

从数据库中获取该用户的权限和菜单信息,并且存入session中。

from django.conf import settings

class InitPermission(object):

    def __init__(self,request,user):
"""
:param request: 传入request对象
:param user: 传入用户对象
""" self.request=request
self.user=user
self.menu_dict={}
self.permissions_dict={} def init_data(self):
"""
从数据库中获取权限信息以及用户信息
:return:
"""
self.permissions_queryset=self.user.roles.filter(permissions__url__isnull=False).values(
'permissions__id',
'permissions__url',
'permissions__title',
'permissions__name',
'permissions__parent_id',
'permissions__parent__name',
'permissions__menu_id',
'permissions__menu__title',
'permissions__menu__icon',
).distinct()
return self.permissions_queryset def init_permissions_dict(self):
"""
构建权限列表,并且存入session
self.permissions_dict={
'customer_list':{'id':1,'url':'/customer/list/','title':'客户列表','pid':'父权限id'}
...
}
:return:
"""
for row in self.init_data():
self.permissions_dict[row['permissions__name']]={
'id':row['permissions__id'],
'url': row['permissions__url'],
'title': row['permissions__title'],
'pid':row['permissions__parent_id'],
'pname':row['permissions__parent__name'],
}
self.request.session[settings.PERMISSION_SESSION_KEY]=self.permissions_dict def init_menu_dict(self):
"""
构建菜单字典并且存入session,之所以构建字典,可以通过键值进行排序
self.menu_dict={
1:{
title:'客户管理',icon:'fa fa-coffe',children:[
{'id':1,'url':'/customer/list/','title':'客户列表'}
...
]
}
}
:return:
"""
for row in self.init_data():
menu_id=row['permissions__menu_id']
if not menu_id:
continue
if menu_id not in self.menu_dict:
self.menu_dict[menu_id]={
'title': row['permissions__menu__title'],
'icon': row['permissions__menu__icon'],
'children': [
{'id':row['permissions__id'],'title': row['permissions__title'], 'url': row['permissions__url']}
]
}
else:
self.menu_dict[menu_id]['children'].append(
{'id': row['permissions__id'], 'title': row['permissions__title'], 'url': row['permissions__url']}
)
self.request.session[settings.MENU_SESSION_KEY] = self.menu_dict

3、权限校验

当用户进行登陆时,需要进行权限校验,通过中间件进行判断。

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,HttpResponse,redirect
from django.conf import settings
import re class PermissionMiddleWare(MiddlewareMixin):
"""
权限控制的中间件
""" def process_request(self, request):
"""
权限控制
:param request:
:return:
"""
# 1. 获取当前请求URL
current_url = request.path_info
print('current_path',current_url) # 1.5 白名单处理
for reg in settings.VALID_URL:
if re.match(reg,current_url):
return None # 2. 获取当前用户session中所有的权限
permissions_dict = request.session.get(settings.PERMISSION_SESSION_KEY)
if not permissions_dict:
return redirect('/login/') # 3. 进行权限校验
flag = False
request.breadcrumb_list=[{'title':'首页','url':'/index/'}]
for item in permissions_dict.values():
id=item['id']
pid=item['pid']
reg = "%s$" % item['url']
print('reg',reg)
if re.match(reg, current_url):
if pid: #访问的是添加客户网页
request.current_menu_id=pid #让它与可以作为权限菜单的客户列表挂钩
###导航条自动生成
request.breadcrumb_list.extend([
{'title':permissions_dict[item['pname']]['title'],'url':permissions_dict[item['pname']]['url']},
{'title':item['title'],'url':item['url']}
]
)
else:
request.current_menu_id=id
###导航条自动生成
request.breadcrumb_list.extend([
{'title':item['title'],'url':item['url']}
]
)
flag = True
break
if not flag:
return HttpResponse('无权访问')

4、前端生成页面

前端生成menu菜单以及breadcrumb导航条

...
<div class="pg-body">
<div class="left-menu">
<div class="menu-body">
{% menu request %}
</div>
</div>
<div class="right-body">
<div>
<ol class="breadcrumb no-radius no-margin" style="border-bottom: 1px solid #ddd;">
{% breadcrumb request %}
</ol>
</div>
{% block content %} {% endblock %}
</div>
</div>
...

menu.py

from django.template import Library
from django.conf import settings
from collections import OrderedDict register=Library() @register.inclusion_tag('rbac/menu.html')
def menu(request):
#获取session中的菜单列表
menu_dict=request.session.get(settings.MENU_SESSION_KEY)
order_dict=OrderedDict()
if menu_dict:
for key in sorted(menu_dict): #按照菜单id升序对菜单进行排序
order_dict[key]=menu_dict[key]
menu_dict[key]['class']='hide'
for child in menu_dict[key]['children']:
if request.current_menu_id==child['id']: #非菜单权限以及菜单权限默认展开
child['class']='active'
menu_dict[key]['class'] = ''
return {"menu_dict":menu_dict} @register.inclusion_tag('rbac/breadcrumb.html')
def breadcrumb(request):
return {'breadcrumb_list':request.breadcrumb_list}
<div class="multi-menu">

    {% for item in menu_dict.values %}
<div class="item">
<div class="title"><span class="icon-wrap"><i class="{{ item.icon }}"></i></span> {{ item.title }}</div>
<div class="body {{ item.class }}">
{% for child in item.children %}
<a href="{{ child.url }}" class="{{ child.class }}">{{ child.title }}</a>
{% endfor %}
</div>
</div>
{% endfor %} </div>

menu.html

{% for item in breadcrumb_list %}
{% if forloop.last %}
<li class="active">{{ item.title }}</li>
{% else %}
<li><a href="{{ item.url }}" >{{ item.title }}</a></li>
{% endif %}
{% endfor %}

breadcrumb.html

最新文章

  1. 校友聊NABCD
  2. vtigerCRM5.4的安装和汉化 ubuntu
  3. 创建一个hibernate helloword
  4. Struts2中date标签乱码问题解决
  5. Activiti5.16.4数据库表结构
  6. Python: 设计模式 之 工厂模式例(1)
  7. python运算符使用规律
  8. opensatck 在启动的时候注入额外的信息
  9. JavaScript设计模式_05_发布订阅模式
  10. 工具 | 代码调试利器fiddle介绍
  11. jQuery+ajax实现局部刷新
  12. Asp.net mvc 5 razor
  13. 【Jest】笔记一:环境配置
  14. HDU5542 The Battle of Chibi
  15. Feign快速入门
  16. 原生js--文档加载时间
  17. 转:Java中字符串split() 的使用方法.
  18. 多线程私有数据pthread_key_create
  19. Composer 技巧(以 FastAdmin 项目为基础)(2018-12-25 更新)
  20. Python(socketserver并发聊天)

热门文章

  1. spoj 371 Boxes【最小费用最大流】
  2. YCOJ中国邮递员问题
  3. div不换行
  4. mybatis 批量insert,update报错 The error occurred while setting parameters
  5. 《windows核心编程系列》一谈谈windows中的错误处理机制
  6. Mybatis事务处理
  7. 【LeetCode 33】Search in Rotated Sorted Array
  8. 聊5块钱P2V
  9. 拼图游戏源码-swift版项目源码
  10. ajax 请求spring之post