LOADING

Follow me

Django Admin
十二月 2, 2013|IT

Django Admin



自定义admin表单

这足以让我们惊讶好几分钟,所有的代码我们都不需要写。

当我们调用admin.site.register(Poll)时,Django只让你编辑这个对象并”推测“怎么把它显示在管理页面上。

很多时候,你可能想要控制admin的样式和功能。你可以在你注册对象的时候把选项告诉Django来实现。

让我们看一下在编辑表单中是怎样实现重新排序字段的。用下面的代码来替换admin.site.register(Poll):

  class PollAdmin(admin.ModelAdmin):

      fields = [‘pub_date’, ‘question’]


  admin.site.register(Poll, PollAdmin)

你将遵循这个模式——创建一个admin模型对象,然后把它传递给admin.site.register()的第二个参数——任何时候你需要修改admin的选项都是修改一个对象。上面具体的改变是”Publication date”字段在”Question”字段的前面:




只有两个字段并不会给人留下深刻的印象,但当admin表单包含有大量字段的时候,选择一个直观的排序方式就是一个重要的细节了。

并且,你可能想要把这些大量的表单字段分割归类为字段集:

  class PollAdmin(admin.ModelAdmin):

      fieldsets = [

          (None,               {‘fields’: [‘question’]}),

          (‘Date information’, {‘fields’: [‘pub_date’]}),

      ]


  admin.site.register(Poll, PollAdmin)

字段集中每个tuple的第一个元素是字段集的标题。现在我们的表单看起来像这样:


 




你可以给每个字段集指定任意的HTML样式。Django提供有一个”collapse”样式,它让每个具体的字段集在初始化时显示为折叠的。

当你的一个很长的表单中包含了许多不常用的字段时,这个样式就显得很实用了:

  class PollAdmin(admin.ModelAdmin):

      fieldsets = [

          (None,               {‘fields’: [‘question’]}),

          (‘Date information’, {‘fields’: [‘pub_date’], ‘classes’: [‘collapse’]}),

      ]


 
添加关联的对象
OK,我们已经有了一个Poll admin页面。但是一个Poll有多个Choice,管理页面并没有显示Choices。

好的。

有两种方法可以解决这个问题。第一种方法是注册admin Choice,就像我们注册Poll那样。这很容易:

  from mysite.polls.models import Choice


  admin.site.register(Choice)

现在Django admin中的”Choices”已经可用了。这个”Add choice”看起来像这样:




在这表单中,”Poll”字段是一个选择框,包含数据库所有的poll。Django知道,外键在admin中代表一个<select>框。

在我们的例子中,只有poll存在外键。

还注意到”Poll”旁边的”Add Another”链接。每个包含有和其它对象构成外键关系的对象都会有这个链接。

当你单击”Add Another”时,你会得到一组带有”Add poll”表单的窗体。

如果你在窗体中添加一个poll并点击”Save”,Django把这个poll保存到数据库中并把它作为选项动态添加到”Add choise”中。

但实际上,这是一种低效的添加Choice对象到系统中的做法。当你在创建Poll对象时,如果你能给它直接添加Choice就更好了。让我们实现它吧。

移去注册Choice模型的register()方法调用。然后,编辑Poll的注册代码:

  class ChoiceInline(admin.StackedInline):

      model = Choice

      extra = 3


  class PollAdmin(admin.ModelAdmin):

      fieldsets = [

          (None,               {‘fields’: [‘question’]}),

          (‘Date information’, {‘fields’: [‘pub_date’], ‘classes’: [‘collapse’]}),

      ]

      inlines = [ChoiceInline]


  admin.site.register(Poll, PollAdmin)

这些代码告诉Django:”Choice对象在Poll的admin page中编辑。默认,为3个choice提供足够的字段。”

加载”Add poll”页面看看它是什么样子的:




它是这样工作的:有3个与Choice相关联的栏——在extra中指定的——每次你返回到一个已经创建的对象的”Change”页面时,你都会得到另外3个的额外栏。

但还是有个小问题。它占据了太多的空间来显示关联对象Choice的所有输入域。对于这个问题,Django提供一种制表的方式来显示关联的对象;

你只需要修改一下ChoiceInline的声明就行了:

  class ChoiceInline(admin.TabularInline):

      #…

使用TabularInline (取代StackedInline), 关联的对象显得更紧凑,它是基于表的格式:


 




自定义admin change list


现在Poll admin页面已经很好了,让我们对”change list”页面做些优化——它用于显示系统中所有的poll。

这是它看起来的样子:




默认,Django显示每个对象的str()。但有时候如果我们能显示个别字段的话会更有效果。

要做到这点,只需使用list_display admin选项,这是一个用于在对象的change list页面内把字段名作为列名显示的tuple:

  class PollAdmin(admin.ModelAdmin):

      # …

      list_display = (‘question’, ‘pub_date’)

  Just for good measure, let’s also include the was_published_today custom method from Tutorial 1:


  class PollAdmin(admin.ModelAdmin):

      # …

      list_display = (‘question’, ‘pub_date’, ‘was_published_today’)

现在,poll change list页面看起来是这样:




你可以点击列头来排序这些值——除了was_published_today头外,因为排序不支持任何方法的输出值。

还注意到was_published_today列头默认是它的方法名(使用下划线替换空格)。但你可以通过给方法一个简短的属性描述来改变这个名:

  def was_published_today(self):

      return self.pub_date.date() == datetime.date.today()

  was_published_today.short_description = ‘Published today?’

让我们对Poll change list页面添加另外的改进:过滤。添加下面的代码到PollAdmin中:

  list_filter = [‘pub_date’]

添加了一个”Filter”侧边栏让人们使用pub_date字段过滤change list:




这个过滤器显示的样式取决于你要过滤的字段的类型。

因为pub_date是DateTimeField,Django知道给DateTimeField一个默认的过滤器:


  ”Any date”,”Today”,”Past 7 days”,”This month”,”This year”。

现在变得更好了。让我们添加一些检索功能:

  search_fields = [‘question’]

为change list添加了一个检索框。当有人输入检索值时,Django会检索question字段。

你可以使用多个检索字段——尽管它使用的是LIKE查询,既保证了自身的可读性,也保证了你的数据库的效率了。

最后,因为Poll对象包含有日期,如果能向下操作就更方便了。添加这行代码:

  date_hierarchy = ‘pub_date’

它在change list页面添加了一个日期分层的导航。在上层,它显示所有可用的年份。然后向下显示月和日。

现在也是一个注意change lists给你提供了免费的分页功能的好时机。

默认是每页显示50条记录。Change-list的分页,检索,过滤,日期分层和列头排序都按照你想要的效果工作了。 


版权声明:本文为博主原创文章,未经博主允许不得转载。

no comments
Share

发表评论