Django:如何在管理页面中显示所有模型字段?

问题描述 投票:0回答:13

这里是模型页面

在这张图片中,这里只显示标题,我用的是:

def __unicode__(self):
    return self.title;  

这是每个单独的对象

如何显示所有这些字段?

如何显示每个模型页面中的所有字段?

django-models django-admin
13个回答
106
投票

要包含所有模型字段而不输入所有字段名称:

list_display = [field.name for field in Book._meta.get_fields()]

以下已弃用的方法已在 Django 1.10 中弃用(请参阅从旧 API 迁移):

list_display = BookAdmin._meta.get_all_field_names()

89
投票

默认情况下,管理布局仅显示从对象的 unicode 函数返回的内容。要显示其他内容,您需要在

app_dir/admin.py
中创建自定义管理表单。

请参阅此处:https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display

您需要添加一个管理表单,并设置

list_display
字段。

在您的具体示例中(admin.py):

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'price')
admin.site.register(Book, BookAdmin)

49
投票

如果您想包含除 ManyToManyField 字段名称之外的所有字段名称,并且它们的顺序与 models.py 文件中的顺序相同,您可以使用:

list_display = [field.name for field in Book._meta.fields if field.name != "id"]

如你所见,我也排除了 id。

如果您发现自己经常这样做,您可以创建 ModelAdmin 的子类:

class CustomModelAdmin(admin.ModelAdmin):
    
    def __init__(self, model, admin_site):
        self.list_display = [field.name for field in model._meta.fields if field.name != "id"]
        super(CustomModelAdmin, self).__init__(model, admin_site)

然后继承它:

class BookAdmin(CustomModelAdmin):
    pass

或者你可以将其作为 mixin 来实现:

class CustomModelAdminMixin(object):

    def __init__(self, model, admin_site):
        self.list_display = [field.name for field in model._meta.fields if field.name != "id"]
        super(CustomModelAdminMixin, self).__init__(model, admin_site)

class TradeAdmin(CustomModelAdminMixin, admin.ModelAdmin):
    pass

如果您想继承 admin.ModelAdmin 之外的其他内容,则 mixin 很有用。


18
投票

我发现OBu在这里的答案对我非常有用。他提到:

缺点是字段是按顺序排列的。

对他的方法进行一个小调整也可以解决这个问题:

list_display  = [f.name for f in Book._meta.fields]

为我工作。


17
投票

大多数答案的问题是,如果您的模型包含

ManyToManyField
ForeignKey
字段,它们就会崩溃。

对于真正的懒人,你可以在你的

admin.py
中做到这一点:

from django.contrib import admin
from my_app.models import Model1, Model2, Model3


@admin.register(Model1, Model2, Model3)
class UniversalAdmin(admin.ModelAdmin):
    def get_list_display(self, request):
        return [field.name for field in self.model._meta.concrete_fields]

9
投票

许多答案都被 Django 1.10 打破了。对于 1.10 或更高版本,这应该是

list_display = [f.name for f in Book._meta.get_fields()]

文档


5
投票

这是我的方法,适用于任何模型类:

MySpecialAdmin = lambda model: type('SubClass'+model.__name__, (admin.ModelAdmin,), {
    'list_display': [x.name for x in model._meta.fields],
    'list_select_related': [x.name for x in model._meta.fields if isinstance(x, (ManyToOneRel, ForeignKey, OneToOneField,))]
})

这会做两件事:

  1. 将所有字段添加到模型管理
  2. 确保每个相关对象只有一个数据库调用(而不是每个实例一个)

然后注册您的模型:

admin.site.register(MyModel, MySpecialAdmin(MyModel))

注意:如果您使用不同的默认模型管理员,请将“admin.ModelAdmin”替换为您的管理员基类


3
投票

显示所有字段:

list_display = [field.attname for field in BookModel._meta.fields]

2
投票

这里找到的每个解决方案都会引发这样的错误

The value of 'list_display[n]' must not be a ManyToManyField.

如果模型包含

Many to Many
字段。

对我有用的可能解决方案是:

list_display = [field.name for field in MyModel._meta.get_fields() if not x.many_to_many]


1
投票

我喜欢这个答案并且认为我应该发布完整的admin.py代码(在这种情况下,我希望所有用户模型字段都出现在admin中)

from django.contrib import admin
from django.contrib.auth.models import User
from django.db.models import ManyToOneRel, ForeignKey, OneToOneField


MySpecialAdmin = lambda model: type('SubClass'+model.__name__, (admin.ModelAdmin,), {
    'list_display': [x.name for x in model._meta.fields],
    'list_select_related': [x.name for x in model._meta.fields if isinstance(x, (ManyToOneRel, ForeignKey, OneToOneField,))]
})

admin.site.unregister(User)
admin.site.register(User, MySpecialAdmin(User))

1
投票

我正在使用 Django

3.1.4
,这是我的解决方案。

我有模特资格

模型.py

from django.db import models

TRUE_FALSE_CHOICES = (
    (1, 'Yes'),
    (0, 'No')
)


class Qualification(models.Model):
    qual_key = models.CharField(unique=True, max_length=20)
    qual_desc = models.CharField(max_length=255)
    is_active = models.IntegerField(choices=TRUE_FALSE_CHOICES)
    created_at = models.DateTimeField()
    created_by = models.CharField(max_length=255)
    updated_at = models.DateTimeField()
    updated_by = models.CharField(max_length=255)

    class Meta:
        managed = False
        db_table = 'qualification'

管理员.py

from django.contrib import admin
from models import Qualification


@admin.register(Qualification)
class QualificationAdmin(admin.ModelAdmin):
    list_display = [field.name for field in Qualification._meta.fields if field.name not in ('id', 'qual_key', 'qual_desc')]
    list_display.insert(0, '__str__')

这里我显示了 list_display 中的所有字段,不包括 'id'、'qual_key'、'qual_desc' 并在开头插入

'__str__'

当您有大量模态字段时,此答案很有帮助,但我建议一一写入所有字段以获得更好的功能。


1
投票

list_display = [Book._meta.get_fields() 中字段的field.name]

即使使用 python 3.9 也应该可以工作

快乐编码


1
投票

我需要显示多个模型的所有字段,我使用了以下样式:

   @admin.register(
        AnalyticsData,
        TechnologyData,
        TradingData,
    )
    class CommonAdmin(admin.ModelAdmin):
        search_fields = ()
    
        def get_list_display(self, request):
            return [
                field.name 
                for field in self.model._meta.concrete_fields 
                if field.name != "id" and not field.many_to_many
            ]

但是,如果您的模型具有不同的字段,您也可以通过创建 mixin 来做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.