八、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

  最終分組完成效果圖如下:

   

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM