當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。