当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python Django ModelAdmin.list_display用法及代码示例


本文介绍 django.contrib.admin.ModelAdmin.list_display 的用法。

声明

ModelAdmin.list_display

设置list_display 来控制在管理员的变更列表页面上显示哪些字段。

例子:

list_display = ('first_name', 'last_name')

如果您不设置 list_display ,管理站点将显示单个列,其中显示每个对象的 __str__() 表示。

list_display 中可以使用四种类型的值。除了最简单的之外,所有的都可以使用 display() 装饰器,它用于自定义字段的呈现方式:

  • 模型字段的名称。例如:

    class PersonAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name')
  • 接受一个参数的可调用对象,即模型实例。例如:

    @admin.display(description='Name')
    def upper_case_name(obj):
        return ("%s %s" % (obj.first_name, obj.last_name)).upper()
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = (upper_case_name,)
  • 表示ModelAdmin 方法的字符串,该方法接受一个参数,即模型实例。例如:

    class PersonAdmin(admin.ModelAdmin):
        list_display = ('upper_case_name',)
    
        @admin.display(description='Name')
        def upper_case_name(self, obj):
            return ("%s %s" % (obj.first_name, obj.last_name)).upper()
  • 表示模型属性或方法的字符串(没有任何必需的参数)。例如:

    from django.contrib import admin
    from django.db import models
    
    class Person(models.Model):
        name = models.CharField(max_length=50)
        birthday = models.DateField()
    
        @admin.display(description='Birth decade')
        def decade_born_in(self):
            return '%d’s' % (self.birthday.year // 10 * 10)
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('name', 'decade_born_in')

关于 list_display 的一些特殊情况需要注意:

  • 如果该字段是 ForeignKey ,Django 将显示相关对象的 __str__()

  • 不支持 ManyToManyField 字段,因为这需要为表中的每一行执行单独的 SQL 语句。如果您仍然想这样做,请给您的模型一个自定义方法,并将该方法的名称添加到 list_display 。 (有关 list_display 中自定义方法的更多信息,请参见下文。)

  • 如果该字段是 BooleanField ,Django 将显示一个漂亮的 “yes”, “no” 或 “unknown” 图标而不是 TrueFalseNone

  • 如果给定的字符串是模型的方法,ModelAdmin 或可调用的,Django 将默认输出HTML-escape。要转义用户输入并允许您自己的未转义标签,请使用 format_html()

    这是一个完整的示例模型:

    from django.contrib import admin
    from django.db import models
    from django.utils.html import format_html
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        color_code = models.CharField(max_length=6)
    
        @admin.display
        def colored_name(self):
            return format_html(
                '<span style="color: #{};">{} {}</span>',
                self.color_code,
                self.first_name,
                self.last_name,
            )
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name', 'colored_name')
  • 正如一些示例已经展示的那样,当使用可调用对象、模型方法或 ModelAdmin 方法时,您可以通过使用 display() 装饰器包装可调用对象并传递 description 参数来自定义列的标题。

    在 Django 3.2 中更改:

    display() 装饰器的description 参数相当于在以前的版本中直接在显示函数上设置short_description 属性。仍然支持直接设置属性以实现向后兼容性。

  • 如果字段的值为 None 、空字符串或没有元素的可迭代对象,Django 将显示 - (破折号)。您可以使用 AdminSite.empty_value_display 覆盖它:

    from django.contrib import admin
    
    admin.site.empty_value_display = '(None)'

    您也可以使用 ModelAdmin.empty_value_display

    class PersonAdmin(admin.ModelAdmin):
        empty_value_display = 'unknown'

    或者在字段级别:

    class PersonAdmin(admin.ModelAdmin):
        list_display = ('name', 'birth_date_view')
    
        @admin.display(empty_value='unknown')
        def birth_date_view(self, obj):
             return obj.birth_date
    在 Django 3.2 中更改:

    display() 装饰器的empty_value 参数相当于在以前的版本中直接在显示函数上设置empty_value_display 属性。仍然支持直接设置属性以实现向后兼容性。

  • 如果给定的字符串是模型的方法、ModelAdmin 或返回 TrueFalseNone 的可调用函数,则 Django 将显示一个漂亮的 “yes”, “no” 或 “unknown” 图标使用 display() 装饰器传递 boolean 参数并将值设置为 True 的方法:

    from django.contrib import admin
    from django.db import models
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        birthday = models.DateField()
    
        @admin.display(boolean=True)
        def born_in_fifties(self):
            return 1950 <= self.birthday.year < 1960
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('name', 'born_in_fifties')
    在 Django 3.2 中更改:

    display() 装饰器的boolean 参数相当于在以前的版本中直接在显示函数上设置boolean 属性。仍然支持直接设置属性以实现向后兼容性。

  • __str__() 方法在 list_display 中与任何其他模型方法一样有效,因此完全可以这样做:

    list_display = ('__str__', 'some_other_field')
  • 通常,不是实际数据库字段的list_display 元素不能用于排序(因为 Django 在数据库级别进行所有排序)。

    但是,如果 list_display 的元素表示某个数据库字段,则可以通过在方法上使用 display() 装饰器并传递 ordering 参数来指示这一事实:

    from django.contrib import admin
    from django.db import models
    from django.utils.html import format_html
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        color_code = models.CharField(max_length=6)
    
        @admin.display(ordering='first_name')
        def colored_first_name(self):
            return format_html(
                '<span style="color: #{};">{}</span>',
                self.color_code,
                self.first_name,
            )
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'colored_first_name')

    上面将告诉 Django 在管理员中尝试按 colored_first_name 排序时按 first_name 字段排序。

    要使用ordering 参数指示降序,您可以在字段名称上使用连字符前缀。使用上面的例子,这看起来像:

    @admin.display(ordering='-first_name')

    ordering 参数支持查询查找以按相关模型上的值排序。此示例在列表显示中包含 “author first name” 列,并允许按名字对其进行排序:

    class Blog(models.Model):
        title = models.CharField(max_length=255)
        author = models.ForeignKey(Person, on_delete=models.CASCADE)
    
    class BlogAdmin(admin.ModelAdmin):
        list_display = ('title', 'author', 'author_first_name')
    
        @admin.display(ordering='author__first_name')
        def author_first_name(self, obj):
            return obj.author.first_name

    查询表达式可以与 ordering 参数一起使用:

    from django.db.models import Value
    from django.db.models.functions import Concat
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
    
        @admin.display(ordering=Concat('first_name', Value(' '), 'last_name'))
        def full_name(self):
            return self.first_name + ' ' + self.last_name
    在 Django 3.2 中更改:

    display() 装饰器的ordering 参数相当于在以前的版本中直接在显示函数上设置admin_order_field 属性。仍然支持直接设置属性以实现向后兼容性。

  • list_display 的元素也可以是属性:

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
    
        @property
        @admin.display(
            ordering='last_name',
            description='Full name of the person',
        )
        def full_name(self):
            return self.first_name + ' ' + self.last_name
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('full_name',)

    请注意,@property 必须高于 @display 。如果您使用旧方法 - 直接设置与显示相关的属性而不是使用 display() 装饰器 - 请注意必须使用 property() 函数而不是 @property 装饰器:

    def my_property(self):
        return self.first_name + ' ' + self.last_name
    my_property.short_description = "Full name of the person"
    my_property.admin_order_field = 'last_name'
    
    full_name = property(my_property)
  • list_display 中的字段名称也将在 HTML 输出中显示为 CSS 类,在每个 <th> 元素上以 column-<field_name> 的形式出现。例如,这可用于设置 CSS 文件中的列宽。

  • Django 将尝试按以下顺序解释 list_display 的每个元素:

    • 模型的一个字段。
    • 一个可调用的。
    • 表示 ModelAdmin 属性的字符串。
    • 表示模型属性的字符串。

    例如,如果您将 first_name 作为模型字段并作为 ModelAdmin 属性,则将使用模型字段。

相关用法


注:本文由纯净天空筛选整理自djangoproject.com大神的英文原创作品 django.contrib.admin.ModelAdmin.list_display。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。