美文网首页Python 学习笔记
自定义更改列表和表单

自定义更改列表和表单

作者: 大爷的二舅 | 来源:发表于2018-02-01 15:03 被阅读9次

    让我们通过指定在我们的作者模型的更改列表上显示的字段来进入管理定制。 默认情况下,更改列表显示每个对象的__str __()的结果。 在第4章中,我们为Author对象定义了__str __()方法来一起显示名字和姓氏:

    class Author(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=40)
        email = models.EmailField(blank=True, verbose_name ='e-mail')
    
        def __str__(self):
            return u'%s %s' % (self.first_name, self.last_name)
    
    
    因此,Author对象的更改列表一起显示彼此的名字和姓氏,如图5-7所示。 图5-7:作者更改列表页面.png

    我们可以通过在更改列表显示中添加一些其他字段来改进此默认行为。 例如,在这个列表中查看每个作者的电子邮件地址是很方便的,并且能够按姓氏排序是很好的。

    为了做到这一点,我们将为Author模型定义一个ModelAdmin类。 这个类是定制管理员的关键,它允许你做的最基本的事情之一是指定要显示在更改列表页面上的字段列表。 编辑admin.py以进行这些更改:

    from django.contrib import admin
    from .models import Publisher, Author, Book
    
    class AuthorAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name', 'email')
    
    admin.site.register(Publisher)
    admin.site.register(Author, AuthorAdmin)
    admin.site.register(Book)
    

    以下是我们所做的:

    • 我们创建了类AuthorAdmin。 这个类是 django.contrib.admin.ModelAdmin的子类,用于保存特定管理模型的自定义配置。 我们只指定了一个定制 - list_display,它被设置为字段名称的元组,以显示在更改列表页面上。 当然,这些字段名称必须存在于模型中。

    • 我们更改了admin.site.register()调用以在Author之后添加AuthorAdmin。 您可以将其读为:“使用AuthorAdmin选项注册作者模型”。admin.site.register()函数将ModelAdmin子类作为可选的第二个参数。 如果你不指定第二个参数(就像Publisher和Book的情况那样),Django将使用该模型的默认管理选项。

    随着这个调整,重新加载作者更改列表页面,你会看到它现在显示三列 - 名字,姓氏和电子邮件地址。 另外,每个列可以通过点击列标题来排序。 (见图5-8) 图5-8:添加完list_display之后的作者更改列表页面.png

    接下来,我们添加一个简单的搜索栏。 将search_fields添加到AuthorAdmin,如下所示:

    class AuthorAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name', 'email')
        search_fields = ('first_name', 'last_name')
    
    在您的浏览器中重新加载页面,您应该在顶部看到一个搜索栏。 (见图5-9)我们刚刚告诉管理员更改列表页面包含一个搜索栏,用于搜索first_name和last_name字段。 用户可能会期望,这是不区分大小写的,并搜索这两个字段,因此搜索字符串“bar”将会找到名字为Barney的作者和名字为Hobarson的作者。 图5-9:添加search_fields之后的作者更改列表页面.png

    接下来,让我们在Book模型的更改列表页面中添加一些日期过滤器:

    from django.contrib import admin
    from .models import Publisher, Author, Book
    
    class AuthorAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name', 'email')
        search_fields = ('first_name', 'last_name')
    
    class BookAdmin(admin.ModelAdmin):
        list_display = ('title', 'publisher', 'publication_date')
        list_filter = ('publication_date',)
    
    admin.site.register(Publisher)
    admin.site.register(Author, AuthorAdmin)
    admin.site.register(Book, BookAdmin)
    
    在这里,因为我们正在处理一组不同的选项,所以我们创建了一个单独的ModelAdmin类 - BookAdmin。 首先,我们定义了一个list_display,以使更改列表看起来更好一些。 然后,我们使用list_filter,它被设置为字段的元组,用来沿着更改列表页面的右侧创建过滤器。 对于日期字段,Django提供了将列表筛选为“今天”,“过去7天”,“本月”和“今年”的快捷方式 - Django开发人员发现的快捷键碰到了按日期过滤的常见情况。 图5-10显示了看起来像什么。 图5-10:list_filter后的book change list页面.png

    list_filter也适用于其他类型的字段,而不仅仅是DateField。 (例如,试试用BooleanField和ForeignKey字段。)只要至少有2个值可供选择,过滤器就会显示出来。 提供日期过滤器的另一种方法是使用date_hierarchy管理选项,如下所示:

    class BookAdmin(admin.ModelAdmin):
        list_display = ('title', 'publisher','publication_date')
        list_filter = ('publication_date',)
        date_hierarchy = 'publication_date'
    
    有了这个,更改列表页面会在列表顶部获得一个日期下拉导航栏,如图5-11所示。 它从一个可用的年份列表开始,然后钻入几个月和个别的日子。 图5-11:date_hierarchy之后的book change list页面.png

    请注意,date_hierarchy接受一个字符串,而不是一个元组,因为只有一个日期字段可以用来建立层次结构。 最后,让我们更改默认排序,以便更改列表页面上的图书总是按发布日期降序排列。

    默认情况下,更改列表根据类Meta中的模型排序(我们将在第4章中介绍)排序对象 - 但是您没有指定此排序值,那么排序是未定义的。

    class BookAdmin(admin.ModelAdmin):
        list_display = ('title', 'publisher','publication_date')
        list_filter = ('publication_date',)
        date_hierarchy = 'publication_date'
        ordering = ('-publication_date',)
    

    此管理排序选项与模型类Meta中的排序完全相同,只是它仅使用列表中的第一个字段名称。 只需传递一个列表或元组的字段名称,并添加一个减号到一个字段使用降序排列顺序。

    重新加载书籍更改列表以查看此操作。 请注意,“发布日期”标题现在包含一个小箭头,指示记录的排序方式。 (见图5-12) 图5-12:订购后的书籍更改列表页面.png

    我们已经介绍了这里的主要更改列表选项。 使用这些选项,您只需几行代码就可以创建一个功能强大的,生产就绪的数据编辑界面。

    自定义编辑表单

    就像更改列表可以自定义一样,编辑表单可以通过多种方式进行自定义。 首先,让我们定制字段的排序方式。 默认情况下,编辑表单中字段的顺序与它们在模型中定义的顺序相对应。 我们可以使用ModelAdmin子类中的fields选项来改变它:

    class BookAdmin(admin.ModelAdmin):
        list_display = ('title', 'publisher', 'publication_date')
        list_filter = ('publication_date',)
        date_hierarchy = 'publication_date'
        ordering = ('-publication_date',)
        fields = ('title', 'authors', 'publisher', 'publication_date')
    

    在这个变化之后,书籍的编辑表单将使用给定的字段顺序。 书名后的作者稍微更自然。 当然,现场订单应该取决于您的数据录入工作流程。 每种形式都是不同的。

    字段选项允许您做的另一个有用的事情是排除某些字段被完全编辑。 只留下你想排除的字段。 如果您的管理员用户只能被信任编辑您的数据的某个部分,或者您的某些字段被某些外部自动化过程所改变,则可以使用此功能。

    例如,在我们的图书数据库中,我们可以将publication_date字段隐藏为可编辑的:

    class BookAdmin(admin.ModelAdmin):
        list_display = ('title', 'publisher','publication_date')
        list_filter = ('publication_date',)
        date_hierarchy = 'publication_date'
        ordering = ('-publication_date',)
        fields = ('title', 'authors', 'publisher')
    

    因此,书籍的编辑表单不提供指定发布日期的方法。这可能是有用的,比方说,如果你是一个编辑,更喜欢他的作者不推迟出版日期。 (当然,这完全是一个假设的例子。)当用户使用这个不完整的表单来添加一本新书时,Django将简单地将publication_date设置为None,所以确保该字段的空值为True。

    另一个常用的编辑表单定制与多对多的字段有关。正如我们在书籍的编辑表格中看到的,管理站点将每个ManyToManyField表示为多选框,这是最合乎逻辑的HTML输入小部件,但多选框可能很难使用。如果要选择多个项目,则必须按住控制键或Mac上的命令才能执行此操作。

    管理站点有助于插入一些解释这一点的文本,但当您的字段包含数百个选项时,它仍然很难使用。管理网站的解决方案是filter_horizo​​ntal。让我们将其添加到BookAdmin,看看它做了什么。

    class BookAdmin(admin.ModelAdmin):
        list_display = ('title', 'publisher','publication_date')
        list_filter = ('publication_date',)
        date_hierarchy = 'publication_date'
        ordering = ('-publication_date',)
        filter_horizontal = ('authors',)
    
    (如果你跟着,请注意,我也删除了字段选项来显示编辑表单中的所有字段。)重新加载图书的编辑表单,你会看到“作者”部分现在使用 花哨的JavaScript过滤器界面,可让您动态搜索选项,并将特定作者从“可用作者”移动到“已选作者”框,反之亦然(图5-13)。 图5-13:添加filter_horizontal之后的图书编辑表单.png

    我强烈建议使用filter_horizo​​ntal任何ManyToManyField有超过10个项目。这比使用简单的多选部件要容易得多。另外,请注意,您可以对多个字段使用filter_horizo​​ntal - 只需在元组中指定每个名称即可。

    ModelAdmin类也支持filter_vertical选项。这与filter_horizo​​ntal完全相同,但生成的JavaScript界面​​将这两个框垂直而不是水平地堆叠起来。这是个人品味的问题。

    filter_horizo​​ntal和filter_vertical仅适用于ManyToManyField字段,而不适用于ForeignKey字段。默认情况下,管理站点对ForeignKey字段使用简单的<select>框,但是对于ManyToManyField,有时您不想承担必须选择要在下拉列表中显示的所有相关对象的开销。

    例如,如果我们的图书数据库增长到包含数千个发布者,则“添加图书”表单可能需要一段时间才能加载,因为它必须加载每个发布者以供在<select>框中显示。解决这个问题的方法是使用一个名为raw_id_fields的选项:

    class BookAdmin(admin.ModelAdmin):
        list_display = ('title', 'publisher','publication_date')
        list_filter = ('publication_date',)
        date_hierarchy = 'publication_date'
        ordering = ('-publication_date',)
        filter_horizontal = ('authors',)
        raw_id_fields = ('publisher',)
    
    将其设置为一个ForeignKey字段名称的元组,这些字段将显示在管理员用一个简单的文本输入框(<input type =“text”>)而不是一个<select>。 见图5-14。 图5-14:添加raw_id_fields之后的图书编辑表单.png

    你在这个输入框里输入什么? 发布者的数据库ID。 鉴于人类通常不会记住数据库ID,还有一个放大镜图标,您可以单击以拉出弹出窗口,您可以从中选择要添加的发布者。

    相关文章

      网友评论

        本文标题:自定义更改列表和表单

        本文链接:https://www.haomeiwen.com/subject/ukcdzxtx.html