第6章介绍了Django的admin界面,现在是回过头来仔细看看这个的时候了
我们前面讲的几次admin是Django的"杀手级特性",并且大多数Django开发人员很快爱上了它节省时间的所有特性
这样自然而然的大部分Django开发人员开始寻找自定义或者扩展admin的方法
第6章最后几部分讲到了一些定制admin界面某一部分的简单方法,重新阅读一下那些资料是个好主意
它讲述了一些定制admin的更改列表,编辑表单以及logo等等的简单方法
第6章也讨论了何时和为什么你想使用admin界面,这些资料跳跃到了其他章节,我们这里重新介绍一下:
显然,admin对编辑数据非常有用(fancy that),如果你有一些录入数据的任务,则admin不可能被其它东西打败
我们料想大多数本书的读者都将有很多数据录入的任务
Django的admin在非技术用户需要录入数据时特别闪耀,这是这个特性的最初起源
尽管如此,我们发现除了显而易见的数据录入任务,admin也在下面一些情况下有用:
1,检查数据模型,我们定义了一个新模型后第一件事就是在admin里调用它并输入一些模拟数据,这对我们发现数据
模型的错误并有一个图形界面来显示这些错误很有帮助
2,管理必须的数据,对于chicagocrime.org来说很少有数据录入的任务,因为它的数据都来自于一个自动的数据源
尽管如此,当自动获取数据的模块出问题时,通过admin可以轻松的编辑数据,这是很有用的
Django的admin不需要或者需要很少配置就可以处理这些常见的情况,但是,处理这些常见的情况如此的好意味着
Django的admin在处理其它情形时不一定很好
我们后面将谈到Django的admin不适合做的一些事情,但是现在我们先离题来看看它的一些哲学:

admin的禅宗
作为它的核心,Django的admin设计用来为如下的一个单独的活动:
受信任的用户编辑结构化的内容
是的,很简单,但是这简单的一行隐藏着很多内容,Django的admin的整个哲学都基于此
让我们深入了解这个句子的子内容:
"受信任的用户"
admin设计来被你(开发者)信任的人用,这不仅仅表示那些被授权的用户,它表示Django假设你的内容编辑者可以
被信任来做正确的事情,这意味着编辑内容没有批准的过程,如果你信任你的用户,没有人需要对编辑的批准
这也表明了权限系统不支持基于一个对象的限制访问
如果你信任某人来编辑他自己的故事,你也将信任他不会在没有权限的情况下编辑别人的故事
"编辑"
Django的admin的首要目的是让人们编辑内容,这最初看起来很显而易见,但是也存在一些细小而强大的影响
例如,尽管admin对重新视查数据很有用,但是它不是设计来干这个的,注意缺少"can view"权限(参考第12章)
Django假设如果用户被允许在admin里查看内容,他们也被允许编辑它
另外一个很值得注意的地方是admin缺少一些例如"工作流"的东西,如果一些任务需要几步来完成,admin不支持
特别的顺序来做这件事情,admin关注于编辑,而不是围绕编辑的其它活动
对于工作流的缺乏支持也起源于信任的原则,admin的哲学是,工作流属于个人问题,而不应该用代码实现
最后,注意admin缺乏统计的支持,它不支持显示总数,平均数等等
再一次说明,admin是用来编辑的,它期望你写自定义的视图来完成其它的任务
"结构化的内容"
因为Django其它部分的关系,admin希望你与结构化的数据工作,这样,admin仅仅支持编辑用Django模型存储的数据
对于其它形式的数据,你则需要自定义视图
总结
现在应该很清楚了,Django的admin不是给任何用户来做任何事情的,而是牢牢的关注一点并且把这一点做的非常好
当我们需要扩展Django的admin时,同一哲学的大部分内容存在与此(注意扩展性无处不在)
因为自定义的Django视图可以做任何事情,而且它们可以可视化的集成到admin(参看下面内容),内建的定制admin的
机会在一定程序上被设计所限制

定制admin模板
我们下面将看到,你有几种工具来定制内建的admin模板,但是对于其它任务,例如需要自定义工作流或者细粒度权限
你将需要阅读本章末尾讲到的定制admin视图
现在我们来看看快速定制admin的外观和行为,第6章讲到了一些常见的任务,如更改logo样式和提供自定义admin表单
就这点来说,我们通常需要更改一个特殊项的一些模板
admin的每一个视图,如更改列表,编辑表单,删除确认页面,历史视图等都有一个分配的模板
而这个模板可以通过几种方式来覆盖
首先,你可以全局覆盖模板,admin视图使用标准模板载入机制来寻找模板,所以如果你在你的模板目录里创建模板
Django将载入并使用这些模板而不是使用Django绑定的默认admin模板
这些全局模板如下:
视图 基本模板名
更改列表 admin/change_list.html
增加/编辑表单 admin/change_form.html
删除确认 admin/delete_confirmation.html
对象历史 admin/object_history.html
尽管如此,大多数情况下你只想更改一个单独的对象或者app的模板而不是全局的模板
这样的话,每个admin视图首先寻找模型和app专有的模板,这些视图按下面的顺序寻找模板:
admin/<app_lable>/<object_name>/<template>.html
admin/<app_lable>/<template>.html
admin/<template>.html
例如,在bookstore app的Book模型的增加/编辑表单的视图(第6章的例子)按下面的顺序寻找模板:
admin/bookstore/book/change_form.html
admin/bookstore/change_form.html
admin/change_form.html

定制模型模板
大多数情况下,你想使用上面第一个模板来创建模型专有的模板
通常情况下通过扩展基本模板并在其中的块定义中添加信息会将这个任务完成的最好
例如我们想在book页面顶端添加一些帮助内容,可能像下面这样:
[img][/img]
这很容易做到,创建一个叫admin/bookstore/book/change_form.html的模板并且插入下面的代码:

  1. {% extends "admin/change_form.html" %}
  2. {% block form_top %}
  3. <p>Insert meaningful help message here..</p>
  4. {% endblock %}
  1. {% extends "admin/change_form.html" %}
  2. {% block form_top %}
  3. <p>Insert meaningful help message here..</p>
  4. {% endblock %}

所有的这些模板都定义了一些块来让你覆盖,对于大多数程序,代码就是最好的文档,所以我们鼓励你浏览admin模板
(在django/contrib/admin/templates/里面)来得到最新的信息

定制JavaScript
使用这个自定义的模型模板最常见的用途就是添加自定义的JavaScript到admin页面,可能是实现一些特殊的小窗口部件
或者是客户端行为
幸运的是,这再简单不过了,每个admin模板定义了一个{% block extrahead %},你可以把使用它来把其它的内容添加
到head元素里去,例如你想在你的一个admin历史页面引入jQuery:

  1. {% extends "admin/object_history.html" %}
  2. {% block extrahead %}
  3. <script src="http://media.example.com/javascript/jquery.js" type="text/javascript"></script>
  4. <script type="text/javascript">
  5. // code to actually use jQuery here...
  6. </script>
  7. {% endblock %}
  1. {% extends "admin/object_history.html" %}
  2. {% block extrahead %}
  3. <script src="http://media.example.com/javascript/jquery.js" type="text/javascript"></script>
  4. <script type="text/javascript">
  5. // code to actually use jQuery here...
  6. </script>
  7. {% endblock %}

我不知道为什么你在对象历史页面需要jQuery,但是这个例子适用于admin的任何模板
你可以使用这个技术来引入任何其它你可能需要的JavaScript小窗口部件

定制admin视图
到目前为止那些想添加自定义行为到Django的admin中的人们可能开始困惑了,他们会喊,"你所讲述的都是关于怎样改变
admin的外观,但是我怎样改变admin的工作方式呢?"
好了,别喊了,这里就是答案
需要理解的第一件事就是它一点也不神奇,admin做的任何事都不特殊,它只是一些像其它视图一样处理数据的视图罢了
这些视图在django.contrib.admin.views,当然这里有很多代码,它必须处理所有的选项,域类型和影响模型行为的设置
同样的,当你意识到admin只是一些视图时,添加自定义的admin视图就变得更容易理解
让我们添加一个"publisher report"视图到我们第6章的book app中,我们将构建一个admin视图来显示通过publisher
分组的books列表,这是一个非常典型你可能想构建的自定义admin"report"的例子
首先我们在URLconf里面包装一个视图,我们需要把这行代码插入到admin视图的引入行之前

  1. (r'^admin/bookstore/report/$', 'bookstore.admin_views.report'),
  1. (r'^admin/bookstore/report/$', 'bookstore.admin_views.report'),

完整的URL配置可能像下面这样:

  1. from django.conf.urls.defaults import *
  2. urlpatterns = patterns('',
  3. (r'^admin/bookstore/report/$', 'bookstore.admin_views.report'),
  4. (r'^admin/', include('django.contrib.admin.urls')),
  5. )
  1. from django.conf.urls.defaults import *
  2. urlpatterns = patterns('',
  3. (r'^admin/bookstore/report/$', 'bookstore.admin_views.report'),
  4. (r'^admin/', include('django.contrib.admin.urls')),
  5. )

为什么把自定义视图放在admin引入之前?回想一下Django处理URL模式的顺序,因为admin的引入URL匹配几乎所有的东西
如果我们把上面的两行URL配置代码调换顺序,Django将会查找一个内建的视图来匹配这个URL,这将不能工作
在这种特殊情况下,Django将试图载入bookstore app的Report模型的更改列表,这是不存在的
现在让我们来写我们的视图,为了简单起见,我们只是载入所有的books在context里并让模板使用{% regroup %}标签处理
分组,用下面的代码创建一个bookstore/admin_views.py文件:

  1. from bookstore.models import Book
  2. from django.template import RequestContext
  3. from django.shortcuts import render_to_response
  4. from django.contrib.admin.views.decorators import staff_member_required
  5. @staff_member_required
  6. def report(request):
  7. return render_to_response(
  8. "admin/bookstore/report.html",
  9. {'book_list' : Book.objects.all()},
  10. RequestContext(request, {}),
  11. )
  1. from bookstore.models import Book
  2. from django.template import RequestContext
  3. from django.shortcuts import render_to_response
  4. from django.contrib.admin.views.decorators import staff_member_required
  5. @staff_member_required
  6. def report(request):
  7. return render_to_response(
  8. "admin/bookstore/report.html",
  9. {'book_list' : Book.objects.all()},
  10. RequestContext(request, {}),
  11. )

因为我们把分组留给模板来做,这个视图非常简单,尽管如此,这里有一些细小的东西值得解释:
1,我们使用django.contrib.admin.views.decorators的staff_member_required装饰器,它类似于第12章讨论的
login_required装饰器,但是这个还检查给定的用户是否标记为"staff"成员来决定是否允许访问admin
这个装饰器保护所有内建的admin视图,让你的视图的认证逻辑和admin的其它部分匹配
2,我们渲染在admin/下面的模板,虽然这没有严格的要求,但是保持你所有的admin模板分组在一个admin目录下
被认为是最佳实践,我们把模板放在我们的app后面叫bookstore的目录下也是最佳实践
3,我们使用RequestContext作为第3个参数(context_instance)传递给render_to_response
这保证了关于当前用户的信息可以在模板里得到,参看第10章得到更多关于RequestContext的信息
最后我们将为这个视图创建一个模板,我们继承内建的admin模板来使这个视图视觉上看起来是admin的一部分:

  1. {% extends "admin/base_site.html" %}
  2. {% block title %}List of books by publisher{% endblock %}
  3. {% block content %}
  4. <div id="content-main">
  5. <h1>List of books by publisher:</h1>
  6. {% regroup book_list|dictsort:"publisher.name" by publisher as books_by_publisher %}
  7. {% for publisher in books_by_publisher %}
  8. <h3>{{ publisher.grouper }}</h3>
  9. <ul>
  10. {% for book in publisher.list|dictsort:"title" %}
  11. <li>{{ book }}</li>
  12. {% endfor %}
  13. </ul>
  14. {% endfor %}
  15. </div>
  16. {% endblock %}
  1. {% extends "admin/base_site.html" %}
  2. {% block title %}List of books by publisher{% endblock %}
  3. {% block content %}
  4. <div id="content-main">
  5. <h1>List of books by publisher:</h1>
  6. {% regroup book_list|dictsort:"publisher.name" by publisher as books_by_publisher %}
  7. {% for publisher in books_by_publisher %}
  8. <h3>{{ publisher.grouper }}</h3>
  9. <ul>
  10. {% for book in publisher.list|dictsort:"title" %}
  11. <li>{{ book }}</li>
  12. {% endfor %}
  13. </ul>
  14. {% endfor %}
  15. </div>
  16. {% endblock %}

通过继承admin/base_site.html我们"免费"得到Django的admin的外观,它看起来像这样:
[img][/img]

今天你需要在哪里使用admin?
你可以使用这个技术来向admin添加任何你想到的东西,记住所谓的"定制admin视图"事实上只是普通的Django视图
你可以使用你在本书其它部分所学的所有技术来构建任意复杂的admin视图
我们将以一些自定义admin视图的一些好注意结束本章内容

覆盖内建的视图
默认的admin视图不包含这些,你可以很轻松的在admin的任何地方跳转到你的自定义视图,只需让你的URL覆盖掉内建的那些
例如,我们可以用一个简单的让用户输入ISBN的表单替代内建的book创建视图,然后我们就可以从http://isbn.nu/来查询
book信息和自动创建对象
这个视图的代码留给读者做练习,最重要的部分是下面的URL配置:

  1. (r'^admin/bookstore/book/add/$', 'bookstore.admin_views.add_by_isbn'),
  1. (r'^admin/bookstore/book/add/$', 'bookstore.admin_views.add_by_isbn'),

如果这段代码在你的URL配置中放在admin的URL前面的话,add_by_isbn视图将完全替代标准的admin视图
我们可以遵循类似的动作来替代删除确认页面,编辑页面或者admin的任何其它部分

自定义Django的admin界面的更多相关文章

  1. Django之admin界面恢复及添加数据模型

    引自:http://fl0wjacky.github.io/jekyll_demo/2014/07/14/Django-admin.html Django之admin界面恢复及添加数据模型 Djang ...

  2. 解决Django的admin界面中文乱码

    解决Django的admin界面中文乱码 问题陈述 最近在做一个很小的Django项目时,使用了自带的sqlite作为数据库.后台admin界面在显示中文数据时,总会遇到乱码.这里截取一小部分代码: ...

  3. 自定义django的admin后台action

    django的admin后台管理系统中自带了一个批量删除所选对象的action. 我们还可以添加自定义的action来实现其它类似的功能,如批量修改某个字段的功能.简单的,例如将文章批量标记为已发布的 ...

  4. 自定义django model form、admin action

    https://www.cnblogs.com/0zcl/archive/2017/03/22/6580279.html 先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin ...

  5. 使用django的admin的后台管理界面

    django的admin后台管理界面是方便我们对数据库操作的  是一个在浏览器显示的  图形化界面数据库操作 我们先在django中的admin中把我们需要在图形化界面中进行操作的表导入进去: 先把m ...

  6. Django笔记 —— Admin(Django站点管理界面)

    最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...

  7. Django---ORM的常用字段和自定义字段,DjangoORM字段与数据库类型对应,字段参数和Meta的参数,Django的admin操作,13中orm操作方法,单标的双下方法

    Django---ORM的常用字段和自定义字段,DjangoORM字段与数据库类型对应,字段参数和Meta的参数,Django的admin操作,13中orm操作方法,单标的双下方法 一丶ORM常用字段 ...

  8. Django 在admin中自定义app名

    前提条件,注册时是: 完整的注册,不是直接用app名进行注册 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'dj ...

  9. 自定义 Django admin 组件

    摘要:学习 Django admin 组件,仿照源码的逻辑,自定义了一个简易的 stark 组件,实现类似 admin 的功能. 可自动生成 url 路由,对于model 有与之相应的配置类对象,可进 ...

随机推荐

  1. python微信公众号开发学习记录

    网上有很多微信公众号的开发教程,但是都是好几年前的了,而且很多都是抄袭其他人的,内容几乎一模一样.真的无语了.只好自己总结一下开发的一些简单流程. 一先去注册个微信公众号,这个就不详细说了, 二登录后 ...

  2. shader cycles静态分析

    mali Mali Offline Compiler https://developer.arm.com/products/software-development-tools/graphics-de ...

  3. rsa实现js前台加密java后台解密

    前段时间写了一个rsa前台加密到后台用java解密,下面共享下实现思路: 准备工作:第三方包是必须的 bcprov-jdk15on-148.jar commons-codec-1.7.jar comm ...

  4. [Python爬虫] 之十五:Selenium +phantomjs根据微信公众号抓取微信文章

    借助搜索微信搜索引擎进行抓取 抓取过程 1.首先在搜狗的微信搜索页面测试一下,这样能够让我们的思路更加清晰 在搜索引擎上使用微信公众号英文名进行“搜公众号”操作(因为公众号英文名是公众号唯一的,而中文 ...

  5. 纯 PHP 代码最好在文件末尾删除 PHP 结束标记

    如果文件内容是纯 PHP 代码,最好在文件末尾删除 PHP 结束标记.这可以避免在 PHP 结束标记之后万一意外加入了空格或者换行符,会导致 PHP 开始输出这些空白,而脚本中此时并无输出的意图. & ...

  6. vue 项目心得

    v-bind 数据绑定 可以简写成 : 通过 props 将数据对象 传给 组件 export default { props: { seller: { type: Object } } } crea ...

  7. Orange的数据挖掘工具入门使用

    Orange的数据挖掘工具入门使用 声明: 1)本报告由博客园bitpeach撰写,版权所有,免费转载,请注明出处,并请勿作商业用途. 2)若本文档内有侵权文字或图片等内容,请联系作者bitpeach ...

  8. Android so文件生成

    http://blog.csdn.net/laczff21/article/details/7542236 http://blog.csdn.net/yhm2046/article/details/8 ...

  9. OJ刷题---简单password破解

    题目要求: 输入代码: #include<iostream> #include <cstdio> #include <cstring> using namespac ...

  10. C8051F340之USB简介

    背景 需求为实现一个键盘产品,于是将C8051F340作为主控制器.本篇记录C8051F340的USB控制器相关知识点,阅读本篇文章需要读者具有最基本的USB相关知识. 正文 C8051F340结构 ...