原文地址:https://docs.djangoproject.com/en/1.4/intro/tutorial02/
这个教程从教程一留下的东西开始的。我们继续网络调查应用程序同时我们将会关注Django的自动生成的管理站点。
(哲学:为你的员工或者客户生成增加,修改或删除内容的站点是一个枯燥无味的工作,因为这不需要太多的创造性。由于这个原因,Django完全自动为模型创建管理接口。Django是在新闻编辑室的环境中开发出来的,当时在“内容发布”和“发布”站点上有一个很明确的区分。站点管理是用系统来增加新的故事,事件,运动得分等等,这些内容发布在公共站点上。Django通过创建一个统一的接口方便管理员编辑内容解决了这一问题。管理站点不是为网站的访问者准备的,它是为网站管理者准备的。)
一、激活管理站点
默认情况下Django不激活管理站点——这是一个选择的东西。为你的程序激活管理站点,做下面三件事:
-
在INSTALLED_APPS设置中取消“django.contrib.admin”的注释。
-
运行python manage.py syncdb。因为你向INSTALLED_APPS增加了新的应用程序,数据库的表需要更新。
-
编辑mysite/urls.py文件,在提到admin的那一行去掉注释——这里总共有三行要取消注释。这个文件是URL配置文件。在下一个教程中我们将深入学习URL配置文件。现在,你只需要知道它映射根URL到你的应用程序。最后你应该有一个像下面一样的urls.py文件:
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', '{{ project_name }}.views.home', name='home'),
# url(r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
二、启动开发服务器
让我们启动开发服务器来探索管理站点。
像教程1中一样通过
python manage.py runserver
来启动开发服务器,现在在打开浏览器在你本地域名后“/admin/”的地方——比如说,http://127.0.0.1:8000/admin/。你应该看到管理员登陆界面:
(和你看到的不一样?:如果这个时候你得到的不是上面的登陆页面,而是错误页面报告的页面就像:
ImportError at /admin/
cannot import name patterns
...
那么可能你使用的Django版本和这个教程版本不匹配。你要吗换到更老的教程或者更新的Django版本。)
三、进入管理站点
现在,尝试着登陆。(你已经在教程1创建了一个超级账户,还记得吗?如果你没有创建或者忘记了密码,你可以再创建一个用户。)你应该看到Django的管理索引页面:
你应该能看到一些编辑内容的东西,包括组,用户和网站。这些默认情况下是Django的核心特征。
四、使调查程序在管理站点中可以修改
但是我们的调查程序在什么地方呢?它还没有在管理索引页面显示出来。
只需要做一件事:我们需要告诉管理站点Poll对象有一个管理接口。为了这样,你可以在polls目录下创建一个叫admin.py文件,编程成下面形式:
from polls.models import Poll
from django.contrib import admin
admin.site.register(Poll)
你需要重新启动开发服务器才能看到这些改变。正常情况下,服务器在你每次修改文件时会自动重新加载代码,但是创建一个新的文件的行为不触发自动加载逻辑。
五、探索管理站点的功能
现在我们已经注册了Poll对象,Django知道它应该在管理索引页面显示出来:
点击”Polls“,现在你在调查程序的”change list“页面了。这个页面显示你数据库中所有的调查,让你可以选择任何一个来改变它。这里有一个我们在教程1创建的“What's up?”调查:
点击“What's up?”来编辑它:
这里需要注意的事情:
页面底部给你许多选项:
-
Save——保存改动,然会返回这种对象类型的改动列表页面;
-
Save and continue editing——保存改动,重新载入对象管理页面;
-
Save and add another——保存改动,载入一个这种对象类型的新的空白表单;
-
Delete——显示一个删除确认页面;
如果“Date published”的值和你在教程1中创建的时间不相同,这可能意味着你忘记了TIME_ZONE的正确值了。修改它,然后重新载入页面检查正确的值是否出现了。
通过点击“Today”和“Now”快捷方式来改变“Date published”。然后点击“Save and continue editing”。然后在右上方点击历史,你可以看到一页列满了通过Django管理站点对这个对象的改动,同时还带有时间戳和改动的用户:
六、定制管理站点表单
花几分钟时间看看你这神奇的代码,虽然你不需要写。通过用admin.site.register(Poll)注册Poll模型,Django能建造一个默认的表单表示方法。通常情况下,你通常想定制管理站点表单的外观和工作方式,这样你可以在你注册对象时告诉Django相关选项。
通过重排序编辑表单的空间来看看这是怎么工作的。把admin.site.register(Poll)行用下面的代替:
class PollAdmin(admin.ModelAdmin):
fields = ['pub_date', 'question']
admin.site.register(Poll, PollAdmin)
任何时候你需要改变对象的管理选项是,你需要遵循这个模式——创建一个模型管理站点对象,然后把它作为第二个参数传递给admin.site.register()。
上面特别地盖面使“Publication date”出现在“Question”之前:
只有两个领域并不让人印象深刻,但是对于许多领域的管理站点表单,选择一个直观的排序是重要的使用细节。
提及许多领域的表单,你可能希望把表单分割成领域块:
class PollAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question']}),
('Date information', {'fields': ['pub_date']}),
]
admin.site.register(Poll, PollAdmin)
领域块中每个元组的第一个元素是领域块的标题,下面是我们的表单外观:
你可以给每个领域块分配绝对的HTML类。Django在初始时提供一个“collapse”类来显示特别地领域块。当你有一个很长并且包含许多不常用的领域的表单时这很有效:
class PollAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
七、增加相关对象
好了,我们有一个Poll对象管理站点页面,但是一个Poll有多个Choices,但是管理站点页面没有显示选择。但是这里有2种方法解决这个问题,第一个是就像我们处理Poll对象一样在admin里注册Choice,这很简单:
from polls.models import Choice
admin.site.register(Choice)
现在,“Choices”在Django的管理页面上可以选择了。“Add choice”表单看起来应该像这样:
在这个表单中,“Poll”区域是数据库中包含每个调查的选择框,Django知道ForeignKey在管理站点中应该作为一个<select>框,在我们的例子中,现在只有一个调查记录存在。
同时注意到“Add Another”链接到下一个“Poll”,每一个拥有ForeignKey关系的对象都能自动这样。当你点击“Add another”,你可以看到一个带有“Add poll”表单的弹出对话框。如果你在这个对话框中增加一个调查记录然后点击“Save”,Django会把这个调查记录保存到数据库,并自动把它加到你在“Add another”下方便你可以做出选择。
但实际上,这种方法向系统增加对象是效率不高的。最好是在创建Poll对象时你能直接增加一些列Choices,让我们实现这个:
删除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:“在Poll管理站点页面上Choice对象时可编辑的,默认情况下,为三个选择提供做够的区域。”
重新载入”Add poll”页面去看看效果,可能你需要重启你的开发服务器:
它就是像这样的。对相关的Choices有三个位置(作为额外特别的),每次你来到一个已经创建的对象的“Change”页面上你,亦可以看到三个额外的位置。
在这三个目前的位置下面你可以找到一个“Add another”链接,如果你点击它,将会创建一个新的位置。如果你想删除增加的位置,你可以点击增加位置右上角的X。注意,你不能删除原始的三个位置。下面显示的是增加了位置的图片:
但是有个小的问题。为进入相关Choice对象已经花了许多屏幕空间用来些事这些领域。由于这个原因,Django提供了显示内联相关对象的表格方式,你需要改变ChoiceInline成下面的样子:
class ChoiceInline(admin.TabularInline):
#...
有了这个TabularInline(而不是StackedInline),相关对象以更紧凑、基于表格格式显示出来:
现在这里有一个额外的“Delete?”栏可以让你删除你用“Add Another Choice”按钮创建并已经保存的行。
八、定制管理站点改动列表
现在Poll管理站点页面看起来还行,就让我们对“change list”(显示系统中所有的调查)做一些调整。
下面是现在站点的样子:
默认情况下,Django显示每个对象的str()。但是有时候当我们想显示个人区域时可能更有用。为了实现这个,我们使用list_display管理选项(这是用来显示的区域名字的元组)在对象改动列表页面作为列:
class PollAdmin(admin.ModelAdmin):
# ...
list_display = ('question', 'pub_date')
为了完善措施,让我们也把教程1的was_published_recently方法加进来:
class PollAdmin(admin.ModelAdmin):
# ...
list_display = ('question', 'pub_date', 'was_published_recently')
现在调查改动列表页面看起来是这样子的:
你可以点击列的标题把这些内容排序(除了was_published_recently列的标题,因为暂不支持绝对方法输出排序)。注意默认情况下was_published_recently列的标题是方法(用下划线替代空格)的名字,每一行包含输出字符串的表示。
你可以像下面一样给方法(在models.py里)一些属性来改善上述现象:
class Poll(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'
再次编辑你的admin.py文件,想Poll改动列表页面增加一个完善:过滤器。把下面的东西增加到PollAdmin:
list_filter = ['pub_date']
这就增加了一个“Filter”边栏让人按照pub_date过滤改动列表:
过滤器显示的种类依赖于你使用过滤器的区域的类型。因为pub_date是DateTimeField,Django知道给一个合适的过滤器选项:“Any date”,“Today”,“Past 7 days”,“This month”,“This year”。
一切进展的都比较顺利。让我们增加一些搜索功能:
search_fields = ['question']
这是在改动列表的顶部增加了一个搜索框。当有人输入搜索条件是,Django会搜索question区域,你可以用你喜欢用的许多区域,尽管因为这是在屏幕后面使用了一个LIKE查询是数据库稳定工作。
最后,因为Poll对象有日期,因此日期的降序排列会更方便。增加下面这行:
date_hierarchy = 'pub_date'
这在改动列表页面的顶部增加了一个按照日期的层次结构。在最上层,它显示所有存在的年。然后向下是月,最终是日。
注意改动列表给了你一个页码。默认情况下每页显示100条记录。改动列表分页,搜索框,过滤器,时间层次结构和列排列都像预期中预期的那样工作。
九、定制管理页面的外观和感觉
很明显,在每个管理页面的顶部有个“Django administration”是很荒唐的。实际上这是放置文本的地方。
但是,使用Django的模板系统很容易改变这个。Django管理系统是由Django自己支持的,它的接口也是Django自己的模板系统。
打开你的设置文件(mysite/settings.py)查看TEMPLATE_DIRS设置。TEMPLATE_DIRS是一个用来检测合适载入Django模板的系统文件目录的元组。它是一个搜索路径。
默认情况下,TEMPLATE_DIRS是空的,因此,让我们给它增加一行告诉Django我们的模板在什么地方:
TEMPLATE_DIRS = (
'/home/my_username/mytemplates', # Change this to your own directory.
)
现在从默认Django的管理模板目录下(Django自身的源代码,django/contrib/admin/template)把 admin/base_site.html拷贝到一个你正在使用的TEMPLATE_DIRS的admin子目录下。比如说,如果你的 TEMPLATE_DIRS是'/home/my_username/mytemplate',像上面说的一样,把django/contrib /admin/templates/base_site.html拷贝到/home/my_username/mytemplates/admin /base_site.html。不要忘记这是一个admin子目录。
(Django源代码文件在哪?:如果找你系统上的Django的源文件有困难,运行下面的命令:
python -c "
import sys
sys.path = sys.path[1:]
import django
print(django.__path__)"
然后只要编辑然后用你自己想用的网站名字替代生成Django的文本。
这个模 板文件包含许多像{% block branding %}和{{ title }}。{%he {{是Django的模板语言的部分标记。当Django提供了admin/base_site.html时,模板语言会自动生成最后的HTML页面。现 在不要担心你一点都看不懂模板——在教程3中我们会深入讲解Django的模板语言。
现在任何Django默认都管理模板都是可以重写的。为了重写一个模板,只要做你对base_site.html做的事情一样就行了——把它从默认地方拷贝到你定制的目录,然后做出相应的改动。
但是机敏的读者会问:如果TEMPLATE_DIRS是空的话,Django怎么找到默认的管理模板呢?其实,默认情况下,Django会在每个应用程序包的templates/子目录下去查找的,作为一个后备。全部信息详见模板载入文档。
十、定制管理索引页面
一个类似的要注意的东西,你可能想定制Django管理索引页面的外观和感觉。
默认情况下,系统按照字母表的顺序显示已经在管理应用程序中注册的INSTALLED_APPS。你可能像对整个布局做出重大改变。毕竟,索引页面可能对管理页面来说是最重要的页面,而且它应该容易使用。
要 定制的莫办事admin/index.html。(就像在前一个部分处理admin/base_site.html一样——从默认的目录复制到你定制模板 的目录。)编辑文件,然后你就能看到它用了一个叫app_list的模板变量。这个变量包含了Django安装的每个应用程序。这并不是使用它,而是你可 以随意用代码把它和明确对象的管理页面相关联。再次,不要担心你不懂模板语言——在教程3中将会涉及到它。
当你据对管理页面适应了,读教程3开始公共调查的视图。
转自:http://my.oschina.net/davidxp/blog/109889
作者: @大海xp