如何在 Django 管理页面中为我的所有模型自动创建 list_filters?

How can I automatically create list_filters for all my models in a django admin page?

我有一个 Django 站点,使用 admin 来管理模型。目前,我正在使用

from django.db.models.base import ModelBase

for name, var in databuild_models.__dict__.items():
    if type(var) is ModelBase:
        admin.site.register(var)

将模块中的所有模型注册到admin模块。但是,我想为每个模型的每个属性自动添加 list_filters。我读过 https://docs.djangoproject.com/en/1.8/ref/contrib/admin/ 他们使用以下形式:

class MymodelAdmin(admin.ModelAdmin):
    list_filter = ['model_name_attribute']

然后是

admin.site.register(models.MyModel, MyModelAdmin)

有没有一种方法可以类似地循环遍历模型中的每个属性,并将其添加到过滤器列表中?

例如:

filter_list_fields = []
for attr in MyModel:
    filter_list_fields.append(str(attr))
list_filter = filter_list_fields

然后将它们注册为一般class?

首先,您可以使用 applications api 获取应用中的模型列表,而不是检查模块的 __dict__

在 Django 1.8+ 中,您可以使用 Model._meta.get_fields 方法获取模型的字段名称列表。我已经排除了自动生成的 id 字段,您可能会发现您想要进一步改进。

在 python 中,您可以使用 type 动态创建 class。您需要新 class 的名称(此处不重要)、它继承自的基础 classes(在本例中为 Admin.ModelAdmin,以及一个属性字典(在本例中,只有一个属性,list_filter).

最后,使用我们创建的自定义模型管理员注册模型。

放在一起,您的 admin.py 应该看起来像这样:

from django.contrib import admin
from django.apps import apps

app_config  = apps.get_app_config('myapp')
models = app_config.get_models()

for Model in models:
    fieldnames = [f.name for f in Model._meta.get_fields() if f.name != 'id']
    ModelAdmin = type('ModelAdmin', (admin.ModelAdmin,), {'list_filter': fieldnames})
    admin.site.register(Model, ModelAdmin)