Django动态渲染多层菜单

为后续给菜单设置权限管理方便,通过给页面模版菜单动态渲染,通过数据菜单表进行匹配需要渲染的菜单

 1 #Django表结构
 2
 3 class Menus(models.Model):
 4
 5     name = models.CharField(max_length=32, verbose_name=u‘菜单名‘)
 6     parent = models.ForeignKey(‘self‘,
 7                                verbose_name=u‘父级菜单‘,
 8                                null=True,
 9                                blank=True,
10                                default=‘0‘,
11                                help_text=u‘如果添加的是子菜单,请选择父菜单‘)
12     show = models.BooleanField(verbose_name=u‘是否显示‘,
13                                default=False,
14                                help_text=u‘菜单是否显示,默认添加不显示‘)
15     url = models.CharField(max_length=300,
16                            verbose_name=u‘菜单url地址‘,
17                            null=True,
18                            blank=True,
19                            default=‘javascript:void(0)‘,
20                            help_text=u‘是否给菜单设置一个url地址‘)
21     priority = models.IntegerField(verbose_name=u‘显示优先级‘,
22                                    null=True,
23                                    blank=True,
24                                    default=-1,
25                                    help_text=u‘菜单的显示顺序,优先级越大显示越靠前‘)
26     permission_id = models.IntegerField(verbose_name=u‘权限编号‘,
27                                         help_text=u‘给菜单设置一个编号,用于权限控制‘,
28                                         error_messages={‘field-permission_id‘: u‘只能输入数字‘})
29
30     def __str__(self):
31         return "{parent}{name}".format(name=self.name, parent="%s-->" % self.parent.name if self.parent else ‘‘)
32
33     class Meta:
34         verbose_name = u"菜单"
35         verbose_name_plural = u"菜单"
36         ordering = ["-priority", "id"]
 1 #admin.py
 2
 3 from django.contrib import admin
 4
 5 # Register your models here.
 6
 7 from cloud.api import models as api_models
 8
 9
10 class MenusAdmin(admin.ModelAdmin):
11     ordering = (‘-parent‘,)
12     list_filter = (‘name‘,)
13     list_display = [‘name‘, ‘parent‘, ‘show‘, ‘url‘, ‘priority‘, ‘permission_id‘]
14     fields = [‘name‘, ‘parent‘, ‘show‘, ‘url‘, ‘priority‘, ‘permission_id‘]
15
16 admin.site.register(api_models.Menus, MenusAdmin)
#  模版中件件,用于在页面返回且将菜单渲染出来

def make_menus_html(menus, parent_id=None, current_parent_id=None, active=None):
    """
    menus = Menus.objects.all()
    :param menus: 寻找的对象,传一个queryset对象
    :param parent_id: 父级菜单ID
    :param current_parent_id: 当前父级菜单ID
    :param active: 激活的菜单名
    :return:
    """
    make_html = ""
    for menu in menus:
        child_menu_flag = "treeview"
        menu_right_flag = ‘<span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span>‘
        child_menu = ‘<li><a href="{menu_url}"><i class="fa fa-circle-o"></i> {menu_name}</a></li>‘
        child_menu_html = ‘<ul class="treeview-menu">{make_child_menu_html}</ul>‘
        master_menu_html = """
        <li class="{child_menu_flag} {active}">
            <a href="{menu_url}"><i class="fa {menu_icon}"></i> <span>{menu_name}</span>{menu_right_flag}</a>
            <ul class="treeview-menu">
            {children_menu_html}
            </ul>
        </li>"""
        children_menu_html = """
        <li class="treeview">
            <a href="{menu_url}"><i class="fa fa-circle-o"></i> <span>{menu_name}</span>{menu_right_flag}</a>
            {child_menu_html}
        </li>"""
        parent = menu.parent  # 获取当前菜单的父级菜单
        if current_parent_id == menu.id or (not parent and current_parent_id):
            continue  # 如果当前父级菜单ID是自己或没有父级菜单且有当前父级ID则跳过本次循环
        if not parent and current_parent_id is None:  # 如果没有父级菜单且当前父级ID是None
            make_children_menu_html = make_menus_html(menus, parent_id=parent_id, current_parent_id=menu.id)
            if not make_children_menu_html:
                menu_right_flag = ‘‘
            menu_icon = "fa-eye"
            if hasattr(menu, ‘icon_name‘):
                menu_icon = menu.icon_name
            if menu.name == active:
                active_menu = ‘active‘
            else:
                active_menu = ‘‘
            make_master_menu_html = master_menu_html.format(child_menu_flag=child_menu_flag,
                                                            active=active_menu,
                                                            menu_url=menu.url,
                                                            menu_icon=menu_icon,
                                                            menu_name=menu.name,
                                                            menu_right_flag=menu_right_flag,
                                                            children_menu_html=make_children_menu_html)
            make_html += make_master_menu_html
        elif parent and current_parent_id == parent.id:  # 如果有父级且当前父级ID是自己的父级ID
            make_child_menu_html = make_menus_html(menus, parent_id=current_parent_id, current_parent_id=menu.id)
            if make_child_menu_html:
                child_menu_html = child_menu_html.format(make_child_menu_html=make_child_menu_html)
                children_menu_html = children_menu_html.format(menu_url=menu.url,
                                                               menu_name=menu.name,
                                                               menu_right_flag=menu_right_flag,
                                                               child_menu_html=child_menu_html)
            else:
                children_menu_html = child_menu.format(menu_url=menu.url, menu_name=menu.name)
            make_html += children_menu_html
        else:
            continue
    return make_html

def make_menus_processor(request):
    menus_obj = Menus.objects.all()
    menus = make_menus_html(menus=menus_obj, active="监控")
    return {‘menus‘: format_html(menus)}

然后通过Django  admin后台添加菜单数据,即可实现层叠动态可折叠菜单,该样式模版基于一个开源的管理模版

https://github.com/almasaeed2010/AdminLTE

时间: 2024-10-27 12:12:16

Django动态渲染多层菜单的相关文章

elementUI 动态渲染三级菜单

后台传的数据为 menuList: [ { name: "首页", pid: 0, id: 28, url: "/main" }, { name: "实时监测", pid: 0, id: 29, url: "/monitoring", childNode: [ { name: "实时监测首页", pid: 29, id: 34, url: "/monitoringHomepage" },

根据权限动态生成二级菜单

数据库models设计: from django.db import models """ 一级菜单 """ class Menu(models.Model): title = models.CharField(max_length=32, unique=True) icon = models.CharField(max_length=32, verbose_name="图标", null=True, blank=True)

vue-router+vuex实现加载动态路由和菜单

前言 动态路由加载和动态菜单渲染的应用在后端权限控制中十分常见,后端只要加载权限路由进行渲染返回到浏览器就可以.在前后端分离中,权限控制动态路由和动态菜单也是一个非常常见的问题.其实我们最最理想的效果是什么呢?我们访问一个应用,在登录之前有哪些路由是一定要加载的呢?你看我总结如下,你看下是不是这些: 1.登录路由 (登录功能路由) 2.系统路由(系统消息路由,比如欢迎界面,404,error等的路由) 但是在vue中,一旦实例化,就必须初始化路由,但这个时候你还没有登录,没有获取你的权限路由呀,

iOS给图片添加滤镜&amp;使用openGLES动态渲染图片

给图片增加滤镜有这两种方式: CoreImage / openGLES 下面先说明如何使用CoreImage给图片添加滤镜, 主要为以下步骤: #1.导入CIImage格式的原始图片 #2.创建CIFilter滤镜 #3.用CIContext将滤镜中的图片渲染出来 #4.导出渲染后的图片 参考代码: 1 //导入CIImage 2 CIImage *ciImage = [[CIImage alloc] initWithImage:[UIImage imageNamed:@"hua"]]

动态生成多级菜单

MVC5+EF6 入门完整教程13 -- 动态生成多级菜单 稍微有一定复杂性的系统,多级菜单都是一个必备组件. 本篇专题讲述如何生成动态多级菜单的通用做法. 我们不用任何第三方的组件,完全自己构建灵活通用的多级菜单. 需要达成的效果:容易复用,可以根据model动态产生. 文章提纲 概述要点 && 理论基础 详细步骤 一.分析多级目录的html结构 二.根据html结构构建data model 三.根据data model动态生成树形结构 四.解析树形结构成html 总结 概述要点 &am

JS动态修改页面EasyUI datebox不生效、EasyUI动态添加Class、EasyUI动态渲染解析解决方案

这是个小菜在实际工作中遇到的问题,相信很多EasyUI新手很可能也遇到这样的问题,因此小菜觉得有必要拿出来分享一下. 这个问题要从EasyUI的datebox组件说起,小菜用这个组件的时候,发现用$("#id").val()这种形式,居然拿不到文本框的值! 经过度娘的帮助,发现可以用$("#id").datebox('getValue'),但是这是为什么捏? 经过一翻研究和探索,小菜发现,如果一个input加上class="easyui-datebox&q

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

用C#从数据库动态生成AdminLTE菜单的一种方法 当前的应用设计风格趋于Flat扁平化,很多基于BootStrap实现了很多UI非常漂亮的管理界面(Bootstrap admin template). 此核心文件开源在Github:https://github.com/JackWangCUMT/AdminLTE-Menu-Generate.首先看一下主界面: 查看左边导航的菜单html结构(下面代码有错误,HTML自定义属性直接用空格进行分割,而不是,号进行分割,不然jquery获取定义属性

在mvc中动态加载菜单

最近做了一个项目, 要在客户端动态的显示菜单,也就是这些菜单是保存在数据库中的, 在客户端动态加载菜单,这样做的好处很明显,就是菜单很容易修改,直接在后台进行维护,再也不会直接在前面的 视图页面中进行修改,但是,缺点也很明显,实现起来有一定的难度,如果菜单多的话,在前台首次加载时,页面就会变慢,我想谈谈自己在这方面的经验 首先, 我们要创建两个表,(其实一个表也可以了,不过那样的话会变得比较复杂), 一个一级分类表, 一个二级分类表, 两个表的结构如下 : 一个是一级分类表,对应的就是父级菜单,

jQuery ui背景色动态渐变导航菜单

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Typ