ModelAdmin属性

用来定制admin的方式大部分都集中在ModelAdmin内置的属性上。ModelAdmin非常灵活,它有许多内置属性,帮助我们自定义admin的界面和功能。

ModelAdmin.actions

要在更改列表页面上提供的操作列表。

ModelAdmin.actions_on_top

是否在列表上方显示acrtions的下拉框,默认为True。

ModelAdmin.actions_on_bottom

是否在列表下方显示actions的下拉框,默认为False。

ModelAdmin.actions_selection_counter

是否在actions下拉框右侧显示选中对象的数量,默认为Ture。

ModelAdmin.date_hierarchy

根据指定的日期相关的字段,为页面创建一个时间导航栏,可通过日期过滤对象。

ModelAdmin.empty_value_dispaly

指定空白显示的内容。如果有些字段没有值,默认情况下会显示破折号”-“。这个选项可以自定义显示的内容。

ModelAdmin.exclude

指定不显示的字段。exclude接收的是一个元组。

ModelAdmin.fields

按设置的顺序显示指定的字段,与exclude恰恰相反。但需要与list_display区分。可以通过组合元组的方式,让某些字段在同一行内显示。

class FlatPageAdmin(admin.ModelAdmin):
    fields = (('url', 'title'), 'content')

如果没有对fields或fieldsets选项进行定义,那么Django将按照模型定义中是顺序,每一行显示一个字段的方式,逐个显示所有的非AutoField和editable=True字段。

ModelAdmin.fieldsets

根据字段对页面进行分组显示或布局。fieldsets是一个二元元组的列表,每个二元元祖代表一个<fieldset>,是整个form的一部分。
二元元组个格式为(name, field_options),name是一个表示该filedset标题的字符串,field_options是一个包含在改fieldset内的字段列表。
示例:

from django.contrib import admin

class FlatPageAdmin(admin.ModelAdmin):
    fieldsets = (
        (None, {
            'fields': ('url', 'title', 'content', 'sites')
        }),
        ('Advanced options', {
            'classes': ('collapse',),
            'fields': ('registration_required', 'template_name'),
        }),
    )

field_options字段内,可以使用的关键字:

  • fields:必填的元组,包含要在fieldsets中显示的字段。同样也可以通过组合元组,实现多个字段在一行内显示的效果。fields可以包含readonly_fields的值,做为只读字段。
  • classes:一个包含额外的CSS类的元组。两个比较有用的样式是collaspe(将fieldsets折叠起来), wide(让它具备更宽的水平空间)。
  • description:一个可选的额外的说明文本,放置在每个fieldsets的顶不。但是这里并没有对它的HTML语法进行转义,要忽略HTML的影响,需要使用django.utils.html.excape手动转义。

ModelAdmin.filter_horizontal

默认情况下,后台站点中ManyToManyField会显示为一个select框,多重使用时比较难使用,将ManyToManyField添加这个属性列表中,页面就会对字段进行扩展,并提供筛选功能。

ModelAdmin.filter_vertical

与ModelAdmin.filter_horizontal相同,但是过滤器界面是一个垂直的。

ModelAdmin.form

默认情况下,admin会自动为模型动态的创建ModelForm,它用于创建 添加/修改 页面的标表单。也可以自己编写自定义的ModelForm,在 添加/修改 页面覆盖默认表单行为。
如果ModelForm和ModelAdmin同时定义了exclude选项,ModelAdmin的优先级更高

ModelAdmin.formfield_overrides

快速覆盖某些字段选项的方法。formfield_overrides是一个字典,它将字段类映射为要在构造时传递字段的参数的字典。
假设自定义了一个RichTextEditorWidget用来代替传统的<textarea>用于输入打断文字,可以这样做:

from django.db import models
from django.contrib import admin
from myapp.widgets import RichTextEditorWidget
from myapp.models import MyModel


class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.TextField: {'widget': RichTextEditorWidget},
    }

注意,字典中的键是实际的字段类,而不是字符串,对应的值又是一个字典,这些参数将被传递给form字段的__init__()方法。
如果想使用一哥带有关系字段的自定义widget,请确保没有在raw_id_fieldsradio_fields中include那些字段的名字。

ModelAdmin.list_display

指定显示在修改页面上的字段。
如果未设置list_display,管理站点将显示一列,显示为每个对象的__str__()方法。
list_dispaly的值类型:

  • 模型字段的名称
      class PersonAdmin(admin.ModelAdmin):
          list_display = ('first_name', 'last_name')
    
  • 接受一个可调用的对象。

      def upper_case_name(obj):
          return ("%s %s" % (obj.first_name, obj.last_name)).upper()
      upper_case_name.short_description = 'Name'
    
      class PersonAdmin(admin.ModelAdmin):
          list_display = (upper_case_name,)
    
  • 一个表示ModelAdmin的某个属性的字符串

      class PersonAdmin(admin.ModelAdmin):
          list_display = ('upper_case_name',)
    
          def upper_case_name(self, obj):
              return ("%s %s" % (obj.first_name, obj.last_name)).upper()
          upper_case_name.short_description = 'Name'
    
  • 表示模型属性或方法的字符串。

      from django.contrib import admin
      from django.db import models
    
      class Person(models.Model):
          name = models.CharField(max_length=50)
          birthday = models.DateField()
    
          def decade_born_in(self):
              return self.birthday.strftime('%Y')[:3] + "0's"
          decade_born_in.short_description = 'Birth decade'
    
      class PersonAdmin(admin.ModelAdmin):
          list_display = ('name', 'decade_born_in')
    
list_display属性需要注意的地方
  • ForeignKey字段,将显示其__str__()方法值。
  • 不支持ManyToMany字段,如果非要显示它,需要自定义方法。
  • BooleanField或NullBollenField字段,会显示on/off而不是True/False。
  • 提供的模型的、ModelAdmin的或者可调用的方法,默认情况下会自动对返回结果进行HTML转义,如果不需要的话,可以使用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)
    
          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')
    
  • 如果某个字段的值为None/空字符串/空的可迭代对象,默认会显示为”-“,可以使用AdminSite.empty_value_display在全局改写这一行。

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

    或者使用Model.empty_value_display值改变某个类的行为:

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

    更加颗粒化:

      class PersonAdmin(admin.ModelAdmin):
          list_display = ('name', 'birth_date_view')
    
          def birth_date_view(self, obj):
               return obj.birth_date
    
          birth_date_view.empty_value_display = 'unknown'
    
  • 如果给定的字符串是模型的方法,如果将方法的给定一个boolean属性为True的话,那么站点页面将会显示一个on/off的图标。

      from django.contrib import admin
      from django.db import models
    
      class Person(models.Model):
          first_name = models.CharField(max_length=50)
          birthday = models.DateField()
    
          def born_in_fifties(self):
              return self.birthday.strftime('%Y')[:3] == '195'
          born_in_fifties.boolean = True
    
      class PersonAdmin(admin.ModelAdmin):
          list_display = ('name', 'born_in_fifties')
    
  • 通过list_dispaly中不是数据库字段的元素不能用于排序,因为Django在数据库级别进行所有排序。但是给这个字段添加一个admin_order_field属性,并复制一个具体的数据库内的字段,则可以按这个字段对原字段进行排序。

      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)
    
          def colored_first_name(self):
              return format_html(
                  '<span style="color: #{};">{}</span>',
                  self.color_code,
                  self.first_name,
              )
          colored_first_name.admin_order_field = 'first_name'
    
      class PersonAdmin(admin.ModelAdmin):
          list_display = ('first_name', 'colored_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')
    
          def author_first_name(self, obj):
              return obj.author.first_name
          author_first_name.admin_order_field = 'author__first_name'
    

    Django2.1以后增加了对表达式的支持:

      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)
    
          def full_name(self):
              return self.first_name + ' ' + self.last_name
          full_name.admin_order_field = Concat('first_name', Value(' '), 'last_name')
    
  • list_display中的元素也可以是某个属性,但是需要注意的是,如果使用Python中的@property来构造一个数行,则不能为它添加short_description描述,只有使用property()函数的方法构造属性时候,才可以添加short_description描述。

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

指定用于链接修改页面的字段。通常情况,list_display列表中的第一个元素将被作为只想目标修改页面的超级链接的锚点。list_display_links可以修改这个默认值。

  • 如果设置为None,那么将没有链接,将无法跳转到目标的修改页面。
  • 设置一个字段的元组或者列表,那么里面的每一个元素都可以链接到目标修改页面。需要注意的是,如果要使用list_display_links,必须在list_display中有相应的元素。

      class PersonAdmin(admin.ModelAdmin):
          list_display = ('first_name', 'last_name', 'birthday')
          list_display_links = ('first_name', 'last_name')
    
      class AuditEntryAdmin(admin.ModelAdmin):
          list_display = ('timestamp', 'message')
          list_display_links = None
    

ModelAdmin.list_editable

指定修改列表的页面中哪些字段可以被编辑,指定字段将显示为编辑框。
需要注意的是,不能将list_display中没有的元素设置为list_editable,不能将list_display_links中的元素设置为list_editable。

ModelAdmin.list_filter

用于激活修改列表页面右边的侧边栏,用于对列表元素进行修改。
list_filter必须是一个元组或者列表,其中的元素必须是以下类型之一:

  • 某字段名,当该字段必须是BooleanField, CharField, DateField, DateTimeField, IntegerField, ForeignKey或ManyToManyField中的一种。

      class PersonAdmin(admin.ModelAdmin):
          list_filter = ('is_staff', 'company')
    
      # 双下划线表示进行跨表关联
      class PersonAdmin(admin.UserAdmin):
          list_filter = ('company__name',)
    
  • 继承django.contrib.admin.SimpleListFilter的类。需要给这个类提供title和parameter_name的值,并重写lookups和queryset方法:

      from datetime import date
      from django.contrib import admin
      from django.utils.translation import ugettext_lazy as _
    
      class DecadeBornListFilter(admin.SimpleListFilter):
          # 提供一个可读的标题
          title = _('出生年代')
    
          # 用于URL查询的参数.
          parameter_name = 'decade'
    
          def lookups(self, request, model_admin):
              """
              返回一个二维元组。每个元组的第一个元素是用于URL查询的真实值,
              这个值会被self.value()方法获取,并作为queryset方法的选择条件。
              第二个元素则是可读的显示在admin页面右边侧栏的过滤选项。        
              """
              return (
                  ('80s', _('80年代')),
                  ('90s', _('90年代')),
              )
    
          def queryset(self, request, queryset):
              """
              根据self.value()方法获取的条件值的不同执行具体的查询操作。
              并返回相应的结果。
              """
              if self.value() == '80s':
                  return queryset.filter(birthday__gte=date(1980, 1, 1),
                                          birthday__lte=date(1989, 12, 31))
              if self.value() == '90s':
                  return queryset.filter(birthday__gte=date(1990, 1, 1),
                                          birthday__lte=date(1999, 12, 31))
    
      class PersonAdmin(admin.ModelAdmin):
    
          list_display = ('first_name', 'last_name', "colored_first_name",'birthday')
    
          list_filter = (DecadeBornListFilter,)
    
  • 可也是一个元组。如果使用RelatedOnlyFieldListFilter限制关联的对象。加入author关联User模型的ForeignKey,将不会显示所有的user,只会显示有外键关联的user。
      class BookAdmin(admin.ModelAdmin):
          list_filter = (
              ('author', admin.RelatedOnlyFieldListFilter),
          )
    

ModelAdmin.list_max_show_all

设置一个数值,控制“显示全部”在修改列表页面上可显示的项目数量,只有当小于或等于时,才会显示。默认为200。

ModelAdmin.list_per_page

设置每页显示多少个元素,默认为100。

如果设置了list_select_related属性,Django将会使用select_related()方法查询个数据,可以减少一些数据库的访问。
属性值可以是布尔值,元组或列表,默认为False。当值为True时,将始终调用select_related()方法;如果这为False,Django将只对list_display属性中ForeignKey字段调用select_related()方法。
也可以设置一个元组或列表对指定元素进行设置:

class ArticleAdmin(admin.ModelAdmin):
    list_select_related = ('author', 'category')

ModelAdmin.ordering

设置排序的方式。属性值必须为一个元组或列表。如果不设置,Djnago将按照默认方式进行排序。如果想进行动态排序,需要自行实现get_ordering()方法。

ModelAdmin.paginator

指定用于分页的分页器。默认情况下,分页器用的是Django自带的django.core.paginator.Paginator。如果自定义分页器的构造函数接口和django.core.paginator.Paginator的不一样,那还需要实现Model.get_paginator()方法。

ModelAdmin.perpopulated_fields

设置预留填充字段。不接收DateTimeField,ForeignKey和ManyToManyField类型的字段。

ModelAdmin.preserve_filters

默认情况下,当对目标进行创建、编辑或删除操作后,页面会依然保持原来的过滤状态。当preserve_filters设置为False后,会返回未过滤状态。

ModelAdmin.radio_fields

默认情况下,Django使用select标签显示ForeignKey或choices集合。如果将这样的字段设置为radio_fields,那么会以radio_box标签的形式展示。

class PersonAdmin(admin.ModelAdmin):
    radio_fields = {"group": admin.VERTICAL}

请勿将ForeignKey或chioces集合之外的字段类型设置给这个属性

ModelAdmin.raw_id_fields

改变默认的ForeignKey和ManyToManyField的展示方式,它会变成一个输入框,用于输入关联对象的主键id。对于ManyToManyField,id以英文逗号分隔。点击放大镜可以查看关联字段。

ModelAdmin.autocompleta_fields

取消关联字典的下拉框,改变成一个输入框,会将输入框中的内容异步对autocompleta_fields中的元素进行香软搜索。

# models.py
from django.db import models


class Tag(models.Model):
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name


class SKillStank(models.Model):
    title = models.CharField(max_length=50)
    tag = models.ManyToManyField("Tag")

# admin.py
from django.contrib import admin
from .models import SKillStank, Tag


@admin.register(SKillStank)
class SkillStankAdmin(admin.ModelAdmin):
    filter_vertical = ("tag",)
    autocomplete_fields = ["tag"]


@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
    ordering = ["id"]
    search_fields = ("name",)

示例的效果图如下:

ModelAdmin.readonly_fields

该属性包含的字段在页面内将展示为布客编辑状态。也可以展示模型或者ModelAdmin本身的方法的返回值。

from django.contrib import admin
from django.utils.html import format_html_join
from django.utils.safestring import mark_safe

class PersonAdmin(admin.ModelAdmin):
    readonly_fields = ('address_report',)

    def address_report(self, instance):
        return format_html_join(
            mark_safe('<br/>'),
            '{}',
            ((line,) for line in instance.get_full_address()),
        ) or mark_safe("<span class='errors'>I can't determine this address.</span>")

    address_report.short_description = "Address"

ModelAdmin.save_as

默认为Fasle。如果设置为True,右下角会多出一个保存为新对象的按钮。

ModelAdmin.save_as_continue

默认为True。保存新对象后悔舔砖到该对象的修改页面,当为False时,将会跳转到修改列表页面。

ModelAdmin.save_on_top

默认为Fasle。如果设置为True,页面的顶部会提供一系列的保存按钮。

ModelAdmin.search_fields

设置这个属性后,修改列表页面将会添加一个搜索框。
被搜索的字段可以是CharField或者TextField,也可以是双下划线的ForeignKey或ManyToManyField。
如果需要执行更加严格的匹配或搜索,可以是用一些元字符。例如:”^”代表从开头匹配, “=”代表区分大小写的并绝对相等的严格匹配。

search_fields = ['^first_name','^last_name']
search_fields = ['=first_name','=last_name']

ModelAdmin.show_full_result_count

用于设置是否显示一个过滤后的对象总数的提示信息。默认情况下它的值为True,将会对整个表进行一个count操作,在表很大的时候,可能会耗费一定的时间和资源。

ModelAdmin.view.on_site

控制是否在admin页面显示查看站点的连接。属性的值可以是布尔值或摸个调用。默认是True,对象get_absolute_url()方法将被调用并生成url。

ModelAdmin.inlines

在修改页面中添加内联模式。

0条评论

相关推荐

django教程

r

Django 2019-05-20 10:53:53

Celery

celery学习资料

Django 2019-05-25 18:41:55

Django-rest-framework教程

django-rest-framework教程。

Django 2019-07-18 16:33:26

django实用资料

django项目从0到1自己总结的实用的资料,大部分常用的功能这里都有

Django 2019-05-08 18:21:34