利用 Django admin 完成更多任务 定制符合您需求的强大应用程(2)

来源:developerWorks 中国 作者:Liza Daly
  

然后在项目中创建以下目录:

$ mkdir templates/admin/examples/document/
$ mkdir templates/admin/examples/comment/

Django admin 的特殊行为将检查目录和应用程序名称(这里是 examples),然后是模型的名称(document 和 comment),然后才能使用系统模版呈现该管理页面。

重写单个模型添加/编辑页面

admin 用来添加和编辑模型实例的页面名称是 change_form.html。首先在 Document 模型目录中创建一个名为 templates/admin/examples/document/change_form.html 的页面,然后将 Django 模版继承线置入其中:{% extends "admin/change_form.html" %}。

现在可以进行定制了。花一些时间熟悉实际的 admin/change_form.html 的内容。它很合理地将一些可以重写的模板块组织到一起,但是有些定制可能需要大量复制模块。不过,使用基于块的模板重写总是比复制整个页面要好。

您想对添加/编辑页面执行哪种定制?对于系统中的每个 Document,您应该展示 5 个最近评论的预览。

首先,创建一些样例内容。


清单 5. 使用 Django shell 创建带几个评论的样例Document
				$ python manage.py shell
In [1]: from examples import models
In [2]: d = models.Document.objects.create(name='Test document', 
                                           text='This is a test document.')
In [3]: for c in range(0, 10):
   ...:     models.Comment.objects.create(text='Comment number %s' % c, document=d)
      

现在,admin 列表页面展示一个 Document。选择该 Document 打开默认的添加/编辑页面,如下所示。


图 3. 带有 Document 的默认添加/编辑页面
默认的添加/编辑页面

注意,相关评论不显示。在 admin 中显示相关模型的标准方法是使用强大的 Inline 类。Inline 类允许 admin 用户在单个页面编辑或添加多个相关模型。要查看运行的 inline,按照清单 6 编辑应用程序 admin.py。


清单 6. 向 Document admin 添加相关模型评论
				from django.contrib import admin
from more_with_admin.examples import models

class CommentInline(admin.TabularInline):
    model = models.Comment

class DocumentAdmin(admin.ModelAdmin):
    inlines = [CommentInline,]

class CommentAdmin(admin.ModelAdmin):
    pass

admin.site.register(models.Document, DocumentAdmin)
admin.site.register(models.Comment, CommentAdmin)
      

图 4 展示了添加 TabularInline 控件之后新的添加/编辑页面。


图 4. 将评论模型作为 Inline 添加之后的添加/编辑页面
将评论模型作为 Inline 添加之后的添加/编辑页面

这无疑非常强大,但是如果只想快速预览评论的话就没必要这样做了。

这里您可以采取两种方法。一种是使用 Django admin widget 接口编辑与 inline 关联的 HTML widget;Django 文档详细描述了 widget。另一种方法是直接修改添加/编辑页面。如果不希望使用任何特定于 admin 的功能,那么该方法非常有用。

如果不允许编辑评论(可能是由于用户没有足够的权限),但是又想 让用户看到评论,那么可以修改 change_form.html。

Django admin 提供的变量

要在模型实例页面添加功能,您需要了解 admin 已经可以使用什么数据。两个键变量的说明如下。


表 1. 定制 admin 模版需要的变量
变量 说明
object_id 这是编辑对象时需要的主键。如果要定义特定的实例页面(比如 Document),那么使用该键就够了。
content_type_id 如果要重写多种模型页面,使用该变量查询 ContentTypes 框架来获取模型的名称。更多有关内容类型的信息,请参见 参考资料。

为 admin 页面中的内容创建模板标记

列出无法直接输入 Django 模板的相关评论查询代码。最佳的解决方案是使用模板标记。首先,创建模板标记目录 and __init__.py 文件:

$ mkdir examples/templatetags/
$ touch examples/templatetags/__init__.py

创建一个名为 examples/templatetags/example_tags.py 的新文件,并添加以下代码。


清单 7. 根据给定 Document ID 检索评论的模板标签
				from django import template
from examples import models

register = template.Library()

@register.inclusion_tag('comments.html')
def display_comments(document_id):
    document = models.Document.objects.get(id__exact=document_id)
    comments = models.Comment.objects.filter(document=document)[0:5]
    return { 'comments': comments }
      

由于这是一个包含标签,您需要创建相应的模板文件:comments.html。编辑 examples/templates/comments.html 文件并输入清单 8 中的代码。


清单 8. 显示评论预览集的模板
				{% for comment in comments %}
<blockquote>{{ comment.text }}</blockquote>
{% endfor %}

现在可以将它添加到 admin 页面了。在 admin.py 中注释掉对 CommentInline 的引用,并按照清单 9 更改 change_form.html 的本地版本。


清单 9. 在添加/编辑页面包含模板标签
				{% extends "admin/change_form.html" %}

{% load example_tags %}

{% block after_field_sets %}
  {% if object_id %}{% display_comments object_id %}{% endif %}
  {% endblock %}

在使用前检查 object_id 的存在很重要,因为 change_form.html 还可以用来创建新实例,在这种情况下 object_id 不可用。after_field_sets 块只是 admin 中提供的众多扩展点之一。其他请参考 change_form.html 源页面。

图 5 展示了更新后的表格。


图 5. 包含模板标记之后的添加/编辑页面
包含模板标记之后的添加/编辑页面





修改 admin 行为

模板重写只能做这么多了。如果您想更改 admin 的实际流和行为怎么办呢?修改源代码不是不可能,但是那会让您受制于更新时使用的特定 Django 版本。

重写 AdminModel 方法

默认情况下,在 admin 中单击 Save 将用户带回到列表页面。通常这没有问题,但是如果您想直接到 admin 外部的对象预览页面,那应该怎么办?在开发内容管理系统 (CMS) 时这种情况很常见。

提供 get_absolute_url() 方法
清单 10 假设已经修改了 Document 以包含 get_absolute_url() 方法,该方法是 Django 模型指定规范表示的推荐方法。如果指定了规范表示,Django admin 还在该模型的每个页面上放置一个有用的 View on site 按钮。

admin 应用程序中的大部分功能都附加到 admin.ModelAdmin 类。这是该对象从 admin.py 中继承的类。您可以重写许多许多公开方法。类定义请查看 admin-source/options.py 中的源代码。

有两种方法可以更改 Save 按钮的行为:您可以重写 admin.ModelAdmin.response_add,该按钮负责保存后的实际重定向;还可以重写 admin.ModelAdmin.change_view。后一种方式更为简单。


清单 10. 保存事件之后重写指向用户的页面
				class DocumentAdmin(admin.ModelAdmin):

    def change_view(self, request, object_id, extra_context=None):

        result = super(DocumentAdmin, self).change_view(request, object_id, extra_context)

        document = models.Document.objects.get(id__exact=object_id)
        
        if not request.POST.has_key('_addanother') and 
              not request.POST.has_key('_continue'):
            result['Location'] = document.get_absolute_url()
        return result

时间:2009-06-22 16:11 来源:developerWorks 中国 作者:Liza Daly 原文链接

好文,顶一下
(7)
87.5%
文章真差,踩一下
(1)
12.5%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量