我想在我的 Django 管理界面中订购模型。默认是应用程序中模型的字母顺序。
我想避免创建额外的包等,或者不得不改变 Django 本身。
这可以通过覆盖 Django 管理模板或其他一些轻量级的方式来完成吗?
编辑:
我不想订购最终项目,例如待办事项列表。
我想在管理员的索引页面中订购不同的模型。例如todos出现在汽车之前。
我想在我的 Django 管理界面中订购模型。默认是应用程序中模型的字母顺序。
我想避免创建额外的包等,或者不得不改变 Django 本身。
这可以通过覆盖 Django 管理模板或其他一些轻量级的方式来完成吗?
编辑:
我不想订购最终项目,例如待办事项列表。
我想在管理员的索引页面中订购不同的模型。例如todos出现在汽车之前。
您可以覆盖模板并添加模板标签进行排序。这是一个片段,它可能需要一些改动http://djangosnippets.org/snippets/1939/
我不认为有一种轻量级的方法可以做到这一点 - 一方面没有工具来存储排序,所以它至少会在某个地方涉及一个新的数据库字段,然后代码获取该字段以找到所需的排序。实际上这可能行不通,因为 AdminSite 是动态构建的,而不是存储在数据库中……嗯,让我们看看 Django 做了什么……
索引模板只是管理员注册的应用程序的循环,并且在每个应用程序中都是模型的循环。它们的顺序由https://github.com/django/django/blob/master/django/contrib/admin/sites.py中的第 384 行定义- 所以一个钩子是继承 AdminSite 并重写 index 方法. 在这里讨论制作新的 AdminSite 事物:https ://docs.djangoproject.com/en/dev/ref/contrib/admin/#adminsite-objects
也许如果您想按照注册的顺序展示模型,您可以在该方法中取出排序线。
我要留下一个不太好的答案。
模型在 django/contrib/admin/sites.py 的第 448 行进行排序
448 # Sort the models alphabetically within each app.
449 for app in app_list:
450 app['models'].sort(key=lambda x: x['name'])
我尚未对此进行测试,但您可以尝试在模型的 Meta 类中添加一个变量,您可以使用该变量在第 403 行的 for 循环中的管理员索引页面中设置模型的顺序。
403 for model, model_admin in self._registry.items():
,,,
431 else:
432 order = model._meta.order
433 app_dict[app_label] = {
434 'order': order,
435 ...
并将排序替换为以下内容:
450 app['models'].sort(key=lambda x: x['order'])
我只是用代理模型做到了这一点,这样模型就可以分组在一个标题下。我意识到您可以通过更改代理模型的 verbose_name 和 verbose_name_plural 来调整排序顺序。因此,可以使用 " " + ._meta.verbose_name 来实现顶级名称,而其他名称可以仅按 1., 2. 3., ... 重新排序
我敢肯定这不是您要找的,但这是我可以达到的轻量级并获得可接受的结果。
# foo/admin.py
from django.contrib import admin
from zoo.models import Zoo
class ZooProxy(Zoo):
class Meta:
proxy = True
app_label = 'foo'
verbose_name = " " + Zoo._meta.verbose_name
verbose_name_plural = " " + Zoo._meta.verbose_name_plural
# one/admin.py
from django.contrib import admin
from one.models import One
class OneProxy(One):
class Meta:
proxy = True
app_label = 'foo'
verbose_name = "2. " + One._meta.verbose_name
verbose_name_plural = "2. " + One._meta.verbose_name_plural
# two/admin.py
from django.contrib import admin
from two.models import Two
class TwoProxy(Two):
class Meta:
proxy = True
app_label = 'foo'
verbose_name = "1. " + Two._meta.verbose_name
verbose_name_plural = "1. " + Two._meta.verbose_name_plural
结果是 django 管理员:
Foo:
Zoo
1. Two
2. One
-vs-
Foo:
One
Two
Zoo
由于我的代码使用 admin.site.register 逐一注册模型,如果 Django 能够记住并使用该顺序,那就太好了。将 django/contrib/admin/sites.py 中的一些字典更改为 OrderedDict() 可能会提供该功能。
这可以通过覆盖默认管理站点并进行一些小的更改来完成:
class MyAdminSite(AdminSite):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._registry = OrderedDict() # remembers the registration order
def get_app_list(self, request):
app_dict = self._build_app_dict(request)
# Sort the apps alphabetically.
app_list = sorted(app_dict.values(), key=lambda x: x['name'].lower())
# disabled the sorting of models
## Sort the models alphabetically within each app.
#for app in app_list:
# app['models'].sort(key=lambda x: x['name'])
return app_list
我不确定 Django 是否提供默认排序,但是您可以使用 ModelAdmin 对象在 Django admin 中添加过滤器和排序窗格。它看起来像这样。
这些更改必须在 admin.py 文件中完成
class PersonAdmin(ModelAdmin):
list_filter = ('is_staff', 'company')
list_filter 将添加可以用于排序和过滤目的的窗格