7

我想在我的 Django 管理界面中订购模型。默认是应用程序中模型的字母顺序。

我想避免创建额外的包等,或者不得不改变 Django 本身。

这可以通过覆盖 Django 管理模板或其他一些轻量级的方式来完成吗?

编辑:

我不想订购最终项目,例如待办事项列表。

我想在管理员的索引页面中订购不同的模型。例如todos出现在汽车之前。

4

6 回答 6

4

您可以覆盖模板并添加模板标签进行排序。这是一个片段,它可能需要一些改动http://djangosnippets.org/snippets/1939/

于 2012-12-23T07:39:09.587 回答
3

我不认为有一种轻量级的方法可以做到这一点 - 一方面没有工具来存储排序,所以它至少会在某个地方涉及一个新的数据库字段,然后代码获取该字段以找到所需的排序。实际上这可能行不通,因为 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

也许如果您想按照注册的顺序展示模型,您可以在该方法中取出排序线。

于 2012-12-23T09:28:25.927 回答
3

我要留下一个不太好的答案。

模型在 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'])
于 2015-10-26T16:39:08.760 回答
2

我只是用代理模型做到了这一点,这样模型就可以分组在一个标题下。我意识到您可以通过更改代理模型的 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
于 2016-03-19T14:45:20.520 回答
0

由于我的代码使用 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
于 2021-12-03T06:48:43.940 回答
-3

我不确定 Django 是否提供默认排序,但是您可以使用 ModelAdmin 对象在 Django admin 中添加过滤器和排序窗格。它看起来像这样。在此处输入图像描述

这些更改必须在 admin.py 文件中完成

class PersonAdmin(ModelAdmin):
    list_filter = ('is_staff', 'company')

list_filter 将添加可以用于排序和过滤目的的窗格

有关更多信息,请查看:https ://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter

于 2012-12-23T06:24:46.880 回答