八、xadmin自定义菜单栏顺序
xadmin默认是读取注册的app和所有注册到xadmin的mode来生成对应的菜单。
nav_menu[app_key] = {
'title': app_title,
'menus': [model_dict],
}
那么如何按照我们自定义的顺序显示菜单的排列顺序呢?
通过查看xadmin的源码,我们可以看出,xadmin的菜单显示分为两部:
1)注册
2)显示
所以对应的我们也可以有两种方式去自定义菜单的显示顺序:
1)在注册的时候让菜单按照我们想要显示的顺序注册并读取
这种方式,需要用到collections模块中的OrderedDict,默认xadmin注册用的是无序字典Dict
2)在读取的时候按需求自定义显示顺序,可以通过变量控制,这种方式相对而言更加的灵活
有了解决思路,那么要考虑的就是怎么样去实现代码功能了。
先说第一种,直接修改_register变量,这种修改方式是最简单的:
xadmin注册的时候,调用的是xadmin.site.register()函数,查看源码我们可以知道,最终是将注册的model信息存在了_register变量中,而_register变量是一个dict,dict是无序的。


但是秉着除非万不得已,我们尽量不要改变库的源码,所以我们需要在外面想办法去修改这个_register变量。
Django项目,在启动时,看wsgi文件中,首先是调用了我们的settings文件,所以我们可以在settings中导入xadmin,然后修改_register,这种修改方法是最简单的

接下来看看第二种修改方式,这种修改方式相对复杂一点,但是却很灵活,可以根据我们的需求随意定制
比如我们可以给菜单分组,排序等都可以按照这种方式进行。
最终读取并渲染到模板是在xadmin.views.bases中的CommAdminView类中完成的,我们可以自定义一个类,并在这个类中重写 get_nav_menu 方法,最后将我们自定义的类注册到xadmin即可
直接上源码:
其中红色部分是自定义用于分组和排序的变量,变量定义在每个app下的apps中

class GlobalSetting(object):
site_title = "上海诺行信息技术有限公司"
site_footer = "COPYRIGHT © 2010 - 2018 ALL RIGHTS RESERVED"
menu_style ="accordion"
apps_icons = {"home":"fa fa-home", "products":"", "companyintroduction":"", "certifications":"fa fa-certificate",
"contactus":"fa fa-phone", "forum":"","logisticinformation":"",
"sourcedownload":"fa fa-download","trade":"fa fa-shopping-cart","users":"fa fa-user",
"wechatuser":"fa fa-user", "knowledgebase":"fa fa-book","questionanswer":"fa fa-question-circle"} @filter_hook
def get_nav_menu(self):
site_menu = list(self.get_site_menu() or [])
had_urls = [] def get_url(menu, had_urls):
if 'url' in menu:
had_urls.append(menu['url'])
if 'menus' in menu:
for m in menu['menus']:
get_url(m, had_urls) get_url({'menus': site_menu}, had_urls) nav_menu = OrderedDict() menus_ = self.admin_site._registry.items()
for model, model_admin in menus_:
if getattr(model_admin, 'hidden_menu', False):
continue
app_label = model._meta.app_label
app_icon = None
model_dict = {
'title': smart_text(capfirst(model._meta.verbose_name_plural)),
'url': self.get_model_url(model, "changelist"),
'icon': self.get_model_icon(model),
'perm': self.get_model_perm(model, 'view'),
'order': model_admin.order,
}
if model_dict['url'] in had_urls:
continue app_key = "app:%s" % app_label
if app_key in nav_menu:
nav_menu[app_key]['menus'].append(model_dict)
else:
# Find app title
app_title = smart_text(app_label.title())
if app_label.lower() in self.apps_label_title:
app_title = self.apps_label_title[app_label.lower()]
else:
appL = apps.get_app_config(app_label)
app_title = smart_text(apps.get_app_config(app_label).verbose_name)
# added by Fiona for menu ordering
if app_label == "auth":
app_index = len(menus_) - 1
elif app_label == "xadmin":
app_index = len(menus_) - 2
else:
app_index = appL.orderIndex_
# find app icon
if app_label.lower() in self.apps_icons:
app_icon = self.apps_icons[app_label.lower()]
nav_menu[app_key] = {
"orderIndex": app_index,
'title': app_title,
'menus': [model_dict],
}
app_menu = nav_menu[app_key]
if app_icon:
app_menu['first_icon'] = app_icon
elif ('first_icon' not in app_menu or
app_menu['first_icon'] == self.default_model_icon) and model_dict.get('icon'):
app_menu['first_icon'] = model_dict['icon'] if 'first_url' not in app_menu and model_dict.get('url'):
app_menu['first_url'] = model_dict['url'] for menu in nav_menu.values():
menu['menus'].sort(key=sortkeypicker(['order', 'title'])) nav_menu = list(nav_menu.values())
# nav_menu.sort(key=lambda x: x['title'])
# 左侧菜单自定义排序新增
nav_menu.sort(key=sortkeypicker(['orderIndex']))
site_menu.extend(nav_menu)
return site_menu
最终分组完成效果图如下:

八、xadmin自定义菜单栏顺序的更多相关文章
- mysql 自定义排序顺序
mysql 自定义排序顺序 实例如:在sql语句中加入ORDER BY FIELD(status,3,4,0,2,1)语句可定义排序顺序 SELECT tsdvoucher0_.VOUCHER_ID ...
- Access 2003 中自定义菜单栏
在Access中如何用自定义的菜单代替Access自带的菜单,现在做一个简单的介绍: 1.打开您做的Access数据库: 2.单击工具栏,选择“自定义…”: 3.在“自定义”窗口,单击“工具栏”选项卡 ...
- django xadmin自定义菜单
1. 自定义菜单 adminx.py class GlobalSetting(object): site_title = u'xxx后台' def kuF_site_menu(self): retur ...
- 五、xadmin自定义插件2
以导入插件为例说明: 1.在xadmin-->plugins下面新建excel.py文件 2.新建ListExcelImportPlugin类,继承BaseAdminPlugin from xa ...
- 四、xadmin自定义插件1
插件原理: Xadmin中每个页面都是一个AdminView对象返回的HTTPResponse结果. Xdamin插件所做的事情就是其实就是在AdminView执行过程中改变其执行逻辑或是改变其返回的 ...
- python测试开发django-44.xadmin自定义菜单项
前言 xadmin后台的菜单项是放到一个app下的,并且里面的排序是按字母a-z排序,有时候我们需要划分多个项,需要自定义菜单列表,可以通过重写CommAdminView类实现. xadmin后台提供 ...
- 八、自定义starter
starter: 1.这个场景需要使用到的依赖是什么? 2.如何编写自动配置 @Configuration //指定这个类是一个配置类 @ConditionalOnXXX //在指定条件成立的情况下自 ...
- xadmin自定义关联菜单
网上好多自定义xadmin后台数据很少有关怎样设置外键关联菜单的显示,如下图所示: 现有个需求根据model中status字段值,来显示关联菜单三道杠,如上图app状态只有是审核成功才会显示,未审核不 ...
- python测试开发django-42.xadmin自定义菜单项
前言 xadmin后台的菜单项是放到一个app下的,并且里面的排序是按字母a-z排序,有时候我们需要划分多个项,需要自定义菜单列表,可以通过重写CommAdminView类实现.xadmin后台提供了 ...
随机推荐
- 简易付XP版本无法获取server.xml配置文件处理方案
博客地址:https://blog.csdn.net/zdw_wym/article/details/40892535 把它添加到C:/WINDOWS/Microsoft.NET/Framework/ ...
- python3+xlwt 读取txt信息并写入到excel中
# coding = utf-8 import os import xlwt import re def readTxt_toExcel(valueList, Pathlist): workbook ...
- ping百度域名时的收获
ping百度 你会发现ping www.baidu.com的时候,会转为ping www.a.shifen.com.但是ping baidu.com的时候却是普通的ip地址,而且ip地址还会变化.那么 ...
- May 25. 2018 Week 21st Friday
Nothing for nothing. 不费力气,就一无所得. These days I am busy in compiling a lightweight communication libra ...
- 比较两个List是否相等,长度和内容都相等
/** *list中存在重复数据,且顺序不一样*/import java.util.ArrayList; import java.util.Collections; import java.util. ...
- Vue编写的todolist小例子
Vue编写的todolist小例子 本篇博客主要包含一个内容: 1.第一个内容:使用Vue编写todolist例子,包含的主要知识是v-model,v-for,el表达式,以及Vue中使用method ...
- MySQL 目录结构、配置文件、修改密码
查看全局数据文件路径 show global variables like "%datadir%" 一.文件目录结构 文件安装路径为F:/JJ/MYSQL-5.6.42-WINX6 ...
- 常用Dockerfile举例
FROM ubuntu:14.04 MAINTAINER sss ENV JAVA_HOME /opt/jdk RUN \ echo 'export PATH=$JAVA_HOME/bin:$PATH ...
- React项目中那些奇怪的写法
1.在一个React组件里看到一个奇怪的写法: const {matchs} = this.props.matchs; 原来,是解构赋值,虽然听说过,但是看起来有点奇怪 下面做个实验: <scr ...
- 基于位置的服务——百度地图SDK练习
基于位置的服务所围绕的核心就是要先确定出用户所在的位置.通常有两种技术方式可以实现:一种是通过GPS定位,一种是通过网络定位.Android对这两种定位方式都提供了相应的API支持.但由于众所周知的原 ...