不修改Django源码让admin中的Model列表按注册顺序显示
from django.contrib import admin
from django.utils.text import capfirst
from django.utils.datastructures import OrderedDict
def find_model_index(name):
count = 0
for model, model_admin in admin.site._registry.items():
if capfirst(model._meta.verbose_name_plural) == name:
return count
else:
count += 1
return count
def index_decorator(func):
def inner(*args, **kwargs):
templateresponse = func(*args, **kwargs)
for app in templateresponse.context_data['app_list']:
app['models'].sort(key=lambda x: find_model_index(x['name']))
return templateresponse
return inner
# registry = OrderedDict()
# registry.update(admin.site._registry)
# admin.site._registry = registry
admin.site.index = index_decorator(admin.site.index)
admin.site.app_index = index_decorator(admin.site.app_index)
由于我使用的是Python3.6,Django2.0,所以字典类型已变成有序的了,就有了上述注释掉的三行代码。
但是上述代码不完善:只对app内部的各个model,根据注册顺序进行了排序。而没有对各个app做排序。
查看源代码,Django是根据字典序排列app的。并不能够自定义。
由于app没有字段来控制排序规则,所以需要加一个:
from django.apps import AppConfig
class DemoConfig(AppConfig):
name = 'demo'
verbose_name = 'Demo'
main_menu_index = 0
通过main_menu_index来排序。完整代码如下:
from django.apps import apps
from django.contrib import admin
from django.utils.text import capfirst
def find_app_index(app_label):
app = apps.get_app_config(app_label)
main_menu_index = getattr(app, 'main_menu_index', 9999)
return main_menu_index
def find_model_index(name):
count = 0
for model, model_admin in admin.site._registry.items():
if capfirst(model._meta.verbose_name_plural) == name:
return count
else:
count += 1
return count
def index_decorator(func):
def inner(*args, **kwargs):
templateresponse = func(*args, **kwargs)
app_list = templateresponse.context_data['app_list']
app_list.sort(key=lambda r: find_app_index(r['app_label']))
for app in app_list:
app['models'].sort(key=lambda x: find_model_index(x['name']))
return templateresponse
return inner
# registry = OrderedDict()
# registry.update(admin.site._registry)
# admin.site._registry = registry
admin.site.index = index_decorator(admin.site.index)
admin.site.app_index = index_decorator(admin.site.app_index)