一、动态显示二级菜单

1、修改权限表结构

  (1)分析需求,要求左侧菜单如下显示:

    客户管理:

      客户列表

    账单管理:

      账单列表

  (2)修改rbac下的models.py,修改后代码如下:

from django.db import models

class User(models.Model):
"""
用户表
"""
name = models.CharField(verbose_name='用户名', max_length=32)
password = models.CharField(verbose_name='密码', max_length=32)
roles = models.ManyToManyField(verbose_name='拥有的所有角色', to='Role')
def __str__(self):
return self.name class Role(models.Model):
"""
角色表
"""
title = models.CharField(verbose_name='角色名称', max_length=32)
permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission')
def __str__(self):
return self.title class Permission(models.Model): # 建立与菜单类的关联,去掉is_menu和icon
"""
权限表
"""
url = models.CharField(verbose_name='含正则的URL', max_length=32)
title = models.CharField(verbose_name='标题', max_length=32)
menu = models.ForeignKey(verbose_name='所属菜单', to="Menu", on_delete=models.CASCADE, null=True)
def __str__(self):
return self.title class Menu(models.Model): # 新增一个菜单表
title = models.CharField(max_length=32, verbose_name='菜单')
icon = models.CharField(max_length=32, verbose_name='图标', null=True, blank=True)

2、注入session(重点是构建数据结构),setsession.py中代码修改如下:

def initial_session(user_obj, request):
"""
将当前登录人的所有权限url列表和自己构建的所有菜单权限字典注入session
:param user_obj: 当前登录用户对象
:param request: 请求对象HttpRequest
"""
# 查询当前登录人的所有权限列表
ret = Role.objects.filter(user=user_obj).values('permissions__url',
'permissions__title',
             'permissions__menu__title',
'permissions__menu__icon',
'permissions__menu__id').distinct()
permission_list = []
permission_menu_dict = {}
for item in ret:
# 获取用户权限列表用于中间件中权限校验
permission_list.append(item['permissions__url'])
menu_pk = item['permissions__menu__id']
if menu_pk:
if menu_pk not in permission_menu_dict:
permission_menu_dict[menu_pk] = {
"menu_title": item["permissions__menu__title"],
"menu_icon": item["permissions__menu__icon"],
"children": [
{
"title": item["permissions__title"],
"url": item["permissions__url"],
}
],
}
else:
permission_menu_dict[menu_pk]["children"].append({
"title": item["permissions__title"],
"url": item["permissions__url"],
})
print('权限列表', permission_list)
print('菜单权限', permission_menu_dict)
# 将当前登录人的权限列表注入session中
request.session['permission_list'] = permission_list
# 将当前登录人的菜单权限字典注入session中
request.session['permission_menu_dict'] = permission_menu_dict

3、从session中取出菜单权限信息,修改my_tags.py文件,代码如下:

from django.template import Library
register =Library() @register.inclusion_tag("menu.html")
def get_menu_styles(request):
permission_menu_dict = request.session.get("permission_menu_dict")
return {"permission_menu_dict": permission_menu_dict}

4、渲染页面,修改menu.html文件,代码如下:

<div class="multi-menu">
{% for item in permission_menu_dict.values %}
<div class="item">
<div class="title">
<i class="{{ item.menu_icon }}"></i>{{ item.menu_title }}
</div>
<div class="body">
{% for foo in item.children %}
<a href="{{ foo.url }}">{{ foo.title }}</a>
{% endfor %}
</div>
</div>
{% endfor %}
</div>

  到此,二级菜单已经渲染到页面中了,样式或者其他js效果就靠你的前端技术了!

二、补充知识点

1、DATABASES的使用

  我们知道django项目使用数据库要在settings.py中通过设置DATABASES给项目配置数据库引擎,我们之前都是给项目设置成MySQL或者django默认的sqlite3数据库,大家知道一个项目可以有多个应用,并且事实也是如此的,每个项目下也会自己的模型类,按照之前的做法,在定义了数据库引擎之后做数据库迁移,那么每个app下的数据库都使用settings中指定的数据库了,但是你可能会有这样的需求,就是不同的应用使用不同的数据库,该如何做呢?没错,也是设置DATABASES,方式如下:

DATABASES = {
'default': { # 下面没有指定的都使用default下的数据库引擎
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'app01':{ # app01使用mysql数据库引擎
'ENGINE': 'django.db.backends.mysql',
'NAME': 'bms', # 要连接的数据库,连接前需要创建好
'USER': 'root', # 连接数据库的用户名
'PASSWORD': '', # 连接数据库的密码
'HOST': '127.0.0.1', # 连接主机,默认本机
'PORT': 3306 # 端口 默认3306
}
}

2、ForeignKey的参数db_constraint解释

  在学习数据库时,我们通过定义外键使两个表建立连接和约束,但有时我们需要只建立连接,不建立约束,也就是通过在表中建立另一个表的id,不设置foreignkey约束。

  Django的ForeignKey也为我们想好了这两种情况:

    (1)db_constraint = True 表示两个表之间既建立了连接又有约束,并支持ORM语法查询;

    (2)db_constraint = False 表示两个表之间只建立了连接,没有建立约束,并支持ORM语法查询;

  注意:当然你可能会想到能否将ForeignKey改为一个IntegerField,通过定义IntegerField字段的值来与另一个表建立联系,这种方法也没错,但是这样就不能使用ORM语法查询,也就享受不到ORM查询的方便,为开发造成了困难,所以不推荐这样做!

 
 
 

django中动态生成二级菜单的更多相关文章

  1. 应用rbac组件 动态生成一级菜单

    动态生成一级菜单 改表结构 需要知道是否是菜单\icon\名称权限表 +字段: is_menu = models.BooleanField(max_length=32,verbose_name='是否 ...

  2. JQuery实现动态生成树形菜单

    jQuery实现动态生成树形菜单 有一个需求:菜单导航条需要依据不同的权限动态提取出来.计划是将功能模块与用户权限之间的关系保持到一个配置表中.所以功能菜单的话就需要动态提取出来再显示.借助jquer ...

  3. jquery 根据后台传递过来的三维数组动态生成三级菜单

    根据后台传递过来的三维数组动态生成三级菜单 <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  4. Celery 分布式任务队列快速入门 以及在Django中动态添加定时任务

    Celery 分布式任务队列快速入门 以及在Django中动态添加定时任务 转自 金角大王 http://www.cnblogs.com/alex3714/articles/6351797.html ...

  5. crm 动态一级二级菜单

    之前代码菜单是写是的 如何 让他 动态 生成了  首先 添加 2个字段 admin.py 更改 显示 from django.contrib import admin from rbac import ...

  6. 用C#从数据库动态生成AdminLTE菜单的一种方法

    当前的应用设计风格趋于Flat扁平化,很多基于BootStrap实现了很多UI非常漂亮的管理界面(Bootstrap admin template). 此核心文件开源在Github:https://g ...

  7. MVC5+EF6 入门完整教程13 -- 动态生成多级菜单

    稍微有一定复杂性的系统,多级菜单都是一个必备组件. 本篇专题讲述如何生成动态多级菜单的通用做法. 我们不用任何第三方的组件,完全自己构建灵活通用的多级菜单. 需要达成的效果:容易复用,可以根据mode ...

  8. EasyUI中动态生成标签页

    这是最近学到的内容,当时是有思路但是不知道怎么获取当前的点击对象,就没有实现功能,通过更深入的学习,我知道了不仅仅是Java,Oracle中有一个this,同样的EasyUI中也存在一个this,来获 ...

  9. django中怎样生成非HTML格式的内容。

    某些时候可能有这种需求.在网页中点击一个链接或者一个button希望返回一张图片.一个pdf文档.一个csv文档等而非HTML. 在diango中非常easy做到这些.django中的view用来接收 ...

随机推荐

  1. Strcpy,strcpy使用注意

    一.char *strcpy(char *dest, const char *src) 参数 dest -- 指向用于存储复制内容的目标数组. src -- 要复制的字符串. 注意: 1.dest需要 ...

  2. day17 python re模块 简易爬虫

    day17 python   一.re模块     1.re模块的基础方法         查找findall() import re #re.findall(pattern,string,flags ...

  3. vue 防止xss攻击

    1.在终端引入xss,命令: npm install xss --save 2.在vue的页面进行引入 import xss from 'xss' 测试 <p v-html="test ...

  4. CF 36E Two Paths

    传送门 真实的自闭= =+ 考试的时候老师明明说了可以路径为空T^T 然后光荣的挂掉了 20分的链[明明是最送分的] 上来就看出来欧拉回路了嘛 然后思考了一下大概奇点配个对 删一条简单路径剩下的跑欧拉 ...

  5. JS中关于引用类型数据及函数的参数传递

    (JavaScript 中,函数的参数传递方式都是按值传递,没有按引用传递的参数) 一.数据类型 在 javascript 中数据类型可以分为两类: 基本类型值 primitive type,比如Un ...

  6. BottomNavigationBar 自定义 底部导航条

    在flutter中,BottomNavigationBar 是底部导航条,可以让我们定义底部 Tab 切换,bottomNavigationBar是 Scaffold 组件的参数. BottomNav ...

  7. BZOJ 5137: [Usaco2017 Dec]Standing Out from the Herd(后缀自动机)

    传送门 解题思路 这个似乎和以前做过的一道题很像,只不过这个是求本质不同子串个数.肯定是先把广义\(SAM\)造出来,然后\(dfs\)时把子节点的信息合并到父节点上,看哪个只被一个串覆盖,\(ans ...

  8. Agri-Net —poj1258

    Agri-Net Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44670   Accepted: 18268 Descri ...

  9. window安装oracle和创建数据库

    原文地址: https://www.cnblogs.com/hoobey/p/6010804.html  #11g安装 https://www.cnblogs.com/qq1272850043/p/6 ...

  10. Transition 过渡/转场动画(一)

    UIViewController 的转场效果 当viewController通过push 或 present 进行转场时, 系统自带的动画是从右侧push进来一个新的viewControler (或从 ...