一、动态显示二级菜单

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. 笔记--NS_SWIFT_NAME与@objc区别与用途

    swift中使用Selector经常要在方法前面添加@objc,除了默认的@objc,其实我们还可以添加自己制定的swift中调用的函数名 @objc(pushToControllerName:par ...

  2. linux清除文件内容

    #以下方式清空文件大小为0 cat /dev/null > catalina.out清除日志文件 $ : > filename $ > filename #以下方式清空文件大小为1 ...

  3. Morphia开发简介

    1. 什么是Morphia Morphia是一个开放源代码的对象关系映射框架,它对MongoDB数据库 java版驱动进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵 ...

  4. python+django+pycharm 环境配置 (window7)

    一.python环境配置 登录python官网,下载windows版的python,本项目使用32位的python2.7.6,下载地址: http://www.python.org/ftp/pytho ...

  5. HTML5知识点总结(一)

    最近在复习前端的基础知识,在这里做一个总结,这是HTML5篇. 新特性 取消了过时的显示效果标记<font></font>和<center></center& ...

  6. LOJ2586 APIO2018 选圆圈

    考前挣扎 KD树好题! 暴力模拟 通过kd树的结构把子树内的圈圈框起来 然后排个序根据圆心距 <= R1+R2来判断是否有交点 然后随便转个角度就可以保持优越的nlgn啦 卡精度差评 必须写ep ...

  7. 分享几套bootstrap后台模板【TP5版】

    分享几套bootstrap后台模板[TP5版],模板来源于网络,需要的拿走.1.AdminLTE 链接: http://pan.baidu.com/s/1o7BXeCM 密码: zfhy 2.Boot ...

  8. C#将Json字符串转化为对象

    实体类: public class CheckData { public string msg; public string code; public string data; public stri ...

  9. java并发编程笔记(八)——死锁

    java并发编程笔记(八)--死锁 死锁发生的必要条件 互斥条件 进程对分配到的资源进行排他性的使用,即在一段时间内只能由一个进程使用,如果有其他进程在请求,只能等待. 请求和保持条件 进程已经保持了 ...

  10. 用shell脚本实现MongoDB数据库自动备份

    一.创建MongoDB备份目录 用来存放数据 mkdir -p /data/mongodb_bak/mongodb_bak_now mkdir -p /data/mongodb_bak/mongodb ...