左侧菜单:
表关系
数据库
class User(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
class Meta:
verbose_name_plural = '用户表'
def __str__(self):
return self.username
#角色表
class Role(models.Model):
caption = models.CharField(max_length=32)#角色
class Meta:
verbose_name_plural = '角色表'
def __str__(self):
return self.caption
#用户分配角色
class User2Role(models.Model):
u = models.ForeignKey(User)#用户表
r = models.ForeignKey(Role)#角色表
class Meta:
verbose_name_plural = '用户分配角色'
def __str__(self):
return "%s-%s" %(self.u.username,self.r.caption,)
#操作表
class Action(models.Model):
# get 获取用户信息1
# post 创建用户2
# delete 删除用户3
# put 修改用户4
caption = models.CharField(max_length=32)#标题
code = models.CharField(max_length=32)#操作
class Meta:
verbose_name_plural = '操作表'
def __str__(self):
return self.caption
#URL表
class Permission(models.Model):
# http://127.0.0.1:8001/user.html 用户管理 1
# http://127.0.0.1:8001/order.html 订单管理 1
caption = models.CharField(max_length=32)#标题
url = models.CharField(max_length=32)#链接
menus=models.ForeignKey("Menus",null=True,blank=True)
class Meta:
verbose_name_plural = 'URL表'
def __str__(self):
return "%s-%s" %(self.caption,self.url,)
class Menus(models.Model):
caption=models.CharField(max_length=32)
parent_id=models.ForeignKey("self",null=True,blank=True)
class Meta:
db_table="Menus"
verbose_name_plural="菜单表"
def __str__(self):
return self.caption
#权限表
class Permission2Action(models.Model):
"""
1 1
1 2
1 3
1 4
2 2
"""
p = models.ForeignKey(Permission)#url
a = models.ForeignKey(Action)#增删改的请求
class Meta:
verbose_name_plural = '权限表'
def __str__(self):
return "%s-%s:-%s?t=%s" %(self.p.caption,self.a.caption,self.p.url,self.a.code,)
#角色分配权限
class Permission2Action2Role(models.Model):
p2a = models.ForeignKey(Permission2Action)#权限表
r = models.ForeignKey(Role)#用户
class Meta:
verbose_name_plural = '角色分配权限'
def __str__(self):
return "%s==>%s" %(self.r.caption,self.p2a,)
获取权限所需的值
#获取当前用户的所有角色列表 role_list=models.Role.objects.filter(user2role__u__username=self.username) #获取当前的权限列表{"p__url":url,"a__code":get} permission2action_list=models.Permission2Action.objects.filter(permission2action2role__r__in=role_list).values("p__url","a__code").distinct() permission2action_dict={}#转换成{"url":get}的格式 for item in permission2action_list: if item["p__url"] in permission2action_dict: permission2action_dict[item["p__url"]]=item["a__code"] else: permission2action_dict[item["p__url"]]=["p__cole"] #获取菜单的叶子节点:即菜单的最后一层权限 menu_leaf_list=list(models.Permission2Action.objects.filter(permission2action2role__r__in=role_list).exclude(p__menus__isnull=True).values("p_id","p__url","p__caption","p__menus").distinct()) #获取所有的菜单列表 menu_list=list(models.Menus.objects.values("id","caption","parent_id"))
生成菜单
menu_leaf_dict={} open_leaf_parent_id=None #归并所有的叶子节点 for item in self.menu_leaf_list: item = { 'id': item['p_id'], 'url': item['p__url'], 'caption': item['p__caption'], 'parent_id': item['p__menus'], 'child': [], 'status': True, # 是否显示 'open': False } #把列表变成字典,key是父级的id if item['parent_id'] in menu_leaf_dict:#把叶子节点同级的挂在一起,挂在父级id上 menu_leaf_dict[item['parent_id']].append(item) else: menu_leaf_dict[item['parent_id']] = [item, ] if re.match(item['url'], self.current_url):#是否是链接的叶子节点 item['open'] = True#有链接的叶子节点加一个状态等于True open_leaf_parent_id = item['parent_id']#重设标志位 # 获取所有菜单字典 menu_dict = {} for item in self.menu_list: #给每个菜单的字典设置初始状态 item['child'] = [] item['status'] = False item['open'] = False menu_dict[item['id']] = item#把列表变成字典key是自己的id # 讲叶子节点添加到菜单中 for k, v in menu_leaf_dict.items():#循环最里层的叶子节点,key是父级的id menu_dict[k]['child'] = v#在菜单字典中id是叶子节点的id,所有在菜单字典中child里可以把最底层的叶子挂上去 parent_id = k#k是叶子节点的父id,是菜单节点的id # 将后代中有叶子节点的菜单标记为【显示】通过while循环把一条线都标记 while parent_id: menu_dict[parent_id]['status'] = True#第一次是叶子节点的父id,当前菜单的id,在菜单把status的状态改成True parent_id = menu_dict[parent_id]['parent_id']#把当前的菜单的父id找到并赋值,每次就找到的父亲 # 将已经选中的菜单标记为【展开】 while open_leaf_parent_id:#等于True表示菜单中有链接,当前连接的一条线标记为True menu_dict[open_leaf_parent_id]['open'] = True open_leaf_parent_id = menu_dict[open_leaf_parent_id]['parent_id'] # 生成树形结构数据 result = []#用来放菜单根的 for row in menu_dict.values():#循环菜单字典 if not row['parent_id']:#判断是否是根 result.append(row) else: menu_dict[row['parent_id']]['child'].append(row)#row['parent_id']是父id, # 把当前菜单挂在父id的child列表里
#result是最后的结果
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> {% block css %} <style> .content{ margin-left: 20px; } .content a{ display: block; } .active{ color: red; } .content .title,a{ {# display: none;#} } .hide{ display: none; } </style> {% endblock %} </head> <body> {% block content %} <div style="float: left;width: 20%"> {{ menu_string |safe }} </div> <div style="float: left;width: 80%"> {% if "get" in action_list %} <a href="http://www.baidu.com">添加</a> {% endif %} </div> {% endblock %} <script src="/static/js/jquery-3.1.1.js"></script> <script> </script> </body> </html>
封装到类里面
左侧菜单简单版
from django.shortcuts import render,HttpResponse # Create your views here. from app01 import models class MenuHelper(object): def __init__(self,id,current_url): self.permission2action_list=None self.result=None self.id=id self.current_url=current_url self.init_data() def init_data(self): role_list=models.Role.objects.filter(user2role__u__id=self.id) permission2action_list=models.Permission2Action.objects.filter(permission2action2role__r__in=role_list).values("p__url","a__code").distinct() self.permission2action_list=permission2action_list #这个人所得到的权限,可保存在session #所有角色在不在这个人的角色里 #必须是要和菜单有关联的不能是空的 menu_leaf_list=models.Permission2Action.objects.filter(permission2action2role__r__in=role_list).exclude(p__menus__isnull=True).values("p_id","p__url","p__caption","p__menus").distinct() #取到的是最底成的链接 menu_leaf_dic={} open_leaf_parent_id=None for item in menu_leaf_list: item={ "id":item["p_id"], "url":item["p__url"], "caption":item["p__caption"], "parent_id":item["p__menus"], "child":[], "status":True, "open":False } #取出最底层的链接转换成字典 if item["parent_id"]in menu_leaf_dic: menu_leaf_dic[item["parent_id"]].append(item) else: menu_leaf_dic[item["parent_id"]]=[item,] #把链接上做一个挂在菜单上的钩子 import re if re.match(item["url"],self.current_url): item["open"]=True#有链接就改变状态 open_leaf_parent_id=item["parent_id"] menu_list=models.Menus.objects.values('id', 'caption', 'parent_id') menu_dict={} for item in menu_list: item["child"]=[] item["status"]=False item["open"]=False menu_dict[item["id"]]=item #取出所有放到字典里 for k,v in menu_leaf_dic.items(): menu_dict[k]["child"]=v#把链接放到菜单上了 parent_id=k while parent_id: #把有东西的菜单的状态变成True menu_dict[parent_id]["status"]=True parent_id=menu_dict[parent_id]["parent_id"] while open_leaf_parent_id: #把需要展开的菜单的状态改变为True menu_dict[open_leaf_parent_id]["open"]=True open_leaf_parent_id=menu_dict[open_leaf_parent_id]["parent_id"] result=[] for item in menu_dict.values(): if not item["parent_id"]: result.append(item) else: menu_dict[item["parent_id"]]["child"].append(item) self.result=result def menu_content(self,child_list): response="" tpl=""" <div class="item %s"> <div class="title">%s</div> <div class="content">%s</div> </div> """ for item in child_list: if not item["status"]: continue hide="" if item["open"]: hide="hide" if "url"in item: response += "<a class='%s' href='%s'>%s</a>" % (hide, item['url'], item['caption']) else: title=item["caption"] content=self.menu_content(item["child"]) response+=tpl%(hide,title,content) return response def menu_tree(self): response="" tpl=""" <div class="item %s"> <div class="title">%s</div> <div class="content">%s</div> </div> """ for item in self.result: if not item["status"]: continue hide="" if item["open"]: hide="hide" title=item["caption"] content=self.menu_content(item["child"]) response+=tpl%(hide,title,content) return response def login(request): # user_request_url = "/product.html" user_request_url = "/order.html" # user_request_url = "/girl.html" id=6 obj = MenuHelper(id, user_request_url) string = obj.menu_tree() return render(request,"index3.html",{"menu_string":string})