自己动手写Django app,第二部分【完】
原文地址: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文件:
01 | from django.conf.urls import patterns, include, url |
02 |
03 | # Uncomment the next two lines to enable the admin: |
04 | from django.contrib import admin |
05 | admin.autodiscover() |
06 |
07 | urlpatterns = patterns('', |
08 | # Examples: |
09 | # url(r'^$', '{{ project_name }}.views.home', name='home'), |
10 | # url(r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')), |
11 |
12 | # Uncomment the admin/doc line below to enable admin documentation: |
13 | # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), |
14 |
15 | # Uncomment the next line to enable the admin: |
16 | url(r'^admin/', include(admin.site.urls)), |
17 | ) |
二、启动开发服务器
让我们启动开发服务器来探索管理站点。
像教程1中一样通过python manage.py runserver来启动开发服务器,现在在打开浏览器在你本地域名后“/admin/”的地方——比如说,http://127.0.0.1:8000/admin/。你应该看到管理员登陆界面:
(和你看到的不一样?:如果这个时候你得到的不是上面的登陆页面,而是错误页面报告的页面就像:
1 | ImportError at /admin/ |
2 | cannot import name patterns |
3 | ... |
三、进入管理站点
现在,尝试着登陆。(你已经在教程1创建了一个超级账户,还记得吗?如果你没有创建或者忘记了密码,你可以再创建一个用户。)你应该看到Django的管理索引页面:
你应该能看到一些编辑内容的东西,包括组,用户和网站。这些默认情况下是Django的核心特征。
四、使调查程序在管理站点中可以修改
但是我们的调查程序在什么地方呢?它还没有在管理索引页面显示出来。
只需要做一件事:我们需要告诉管理站点Poll对象有一个管理接口。为了这样,你可以在polls目录下创建一个叫admin.py文件,编程成下面形式:
1 | from polls.models import Poll |
2 | from django.contrib import admin |
3 |
4 | admin.site.register(Poll) |
你需要重新启动开发服务器才能看到这些改变。正常情况下,服务器在你每次修改文件时会自动重新加载代码,但是创建一个新的文件的行为不触发自动加载逻辑。
五、探索管理站点的功能
现在我们已经注册了Poll对象,Django知道它应该在管理索引页面显示出来:
点击”Polls“,现在你在调查程序的”change list“页面了。这个页面显示你数据库中所有的调查,让你可以选择任何一个来改变它。这里有一个我们在教程1创建的“What's up?”调查:
点击“What's up?”来编辑它:
这里需要注意的事情:
表单是Poll模型自动生成的;
不同的模型的空间类型(DataTimeField,CharField)对应着相关的HTML输入部件,每个空间类型知道如何在Django管理页面中显示它自己;
每个DateTimeField能获得一个免费的JavaScript的快捷方式。日期获得一个“Today”的快捷方式和日历弹出对话框,时间获得一个“Now”快捷方式和一个方便的列举常用进入时间的对出框;
页面底部给你许多选项:
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)行用下面的代替:
1 | class PollAdmin(admin.ModelAdmin): |
2 | fields = ['pub_date', 'question'] |
3 |
4 | admin.site.register(Poll, PollAdmin) <span></span> |
任何时候你需要改变对象的管理选项是,你需要遵循这个模式——创建一个模型管理站点对象,然后把它作为第二个参数传递给admin.site.register()。
上面特别地盖面使“Publication date”出现在“Question”之前:
只有两个领域并不让人印象深刻,但是对于许多领域的管理站点表单,选择一个直观的排序是重要的使用细节。
提及许多领域的表单,你可能希望把表单分割成领域块:
1 | class PollAdmin(admin.ModelAdmin): |
2 | fieldsets = [ |
3 | (None, {'fields': ['question']}), |
4 | ('Date information', {'fields': ['pub_date']}), |
5 | ] |
6 |
7 | admin.site.register(Poll, PollAdmin) |
你可以给每个领域块分配绝对的HTML类。Django在初始时提供一个“collapse”类来显示特别地领域块。当你有一个很长并且包含许多不常用的领域的表单时这很有效:
1 | class PollAdmin(admin.ModelAdmin): |
2 | fieldsets = [ |
3 | (None, {'fields': ['question']}), |
4 | ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), |
5 | ] |
七、增加相关对象
好了,我们有一个Poll对象管理站点页面,但是一个Poll有多个Choices,但是管理站点页面没有显示选择。但是这里有2种方法解决这个问题,第一个是就像我们处理Poll对象一样在admin里注册Choice,这很简单:
1 | from polls.models import Choice |
2 |
3 | admin.site.register(Choice) |
在这个表单中,“Poll”区域是数据库中包含每个调查的选择框,Django知道ForeignKey在管理站点中应该作为一个<select>框,在我们的例子中,现在只有一个调查记录存在。
同时注意到“Add Another”链接到下一个“Poll”,每一个拥有ForeignKey关系的对象都能自动这样。当你点击“Add another”,你可以看到一个带有“Add poll”表单的弹出对话框。如果你在这个对话框中增加一个调查记录然后点击“Save”,Django会把这个调查记录保存到数据库,并自动把它加到你在“Add another”下方便你可以做出选择。
但实际上,这种方法向系统增加对象是效率不高的。最好是在创建Poll对象时你能直接增加一些列Choices,让我们实现这个:
删除Choice模型的register()调用函数,然后编辑Poll注册代码如下:
01 | class ChoiceInline(admin.StackedInline): |
02 | model = Choice |
03 | extra = 3 |
04 |
05 | class PollAdmin(admin.ModelAdmin): |
06 | fieldsets = [ |
07 | (None, {'fields': ['question']}), |
08 | ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), |
09 | ] |
10 | inlines = [ChoiceInline] |
11 |
12 | admin.site.register(Poll, PollAdmin) |
重新载入”Add poll”页面去看看效果,可能你需要重启你的开发服务器:
它就是像这样的。对相关的Choices有三个位置(作为额外特别的),每次你来到一个已经创建的对象的“Change”页面上你,亦可以看到三个额外的位置。
在这三个目前的位置下面你可以找到一个“Add another”链接,如果你点击它,将会创建一个新的位置。如果你想删除增加的位置,你可以点击增加位置右上角的X。注意,你不能删除原始的三个位置。下面显示的是增加了位置的图片:
但是有个小的问题。为进入相关Choice对象已经花了许多屏幕空间用来些事这些领域。由于这个原因,Django提供了显示内联相关对象的表格方式,你需要改变ChoiceInline成下面的样子:
1 | class ChoiceInline(admin.TabularInline): |
2 | #... |
现在这里有一个额外的“Delete?”栏可以让你删除你用“Add Another Choice”按钮创建并已经保存的行。
八、定制管理站点改动列表
现在Poll管理站点页面看起来还行,就让我们对“change list”(显示系统中所有的调查)做一些调整。
下面是现在站点的样子:
默认情况下,Django显示每个对象的str()。但是有时候当我们想显示个人区域时可能更有用。为了实现这个,我们使用list_display管理选项(这是用来显示的区域名字的元组)在对象改动列表页面作为列:
1 | class PollAdmin(admin.ModelAdmin): |
2 | # ... |
3 | list_display = ('question', 'pub_date') |
1 | class PollAdmin(admin.ModelAdmin): |
2 | # ... |
3 | list_display = ('question', 'pub_date', 'was_published_recently') |
你可以点击列的标题把这些内容排序(除了was_published_recently列的标题,因为暂不支持绝对方法输出排序)。注意默认情况下was_published_recently列的标题是方法(用下划线替代空格)的名字,每一行包含输出字符串的表示。
你可以像下面一样给方法(在models.py里)一些属性来改善上述现象:
1 | class Poll(models.Model): |
2 | # ... |
3 | def was_published_recently(self): |
4 | return self.pub_date >= timezone.now() - datetime.timedelta(days=1) |
5 | was_published_recently.admin_order_field = 'pub_date' |
6 | was_published_recently.boolean = True |
7 | was_published_recently.short_description = 'Published recently?' |
1 | list_filter = ['pub_date'] |
过滤器显示的种类依赖于你使用过滤器的区域的类型。因为pub_date是DateTimeField,Django知道给一个合适的过滤器选项:“Any date”,“Today”,“Past 7 days”,“This month”,“This year”。
一切进展的都比较顺利。让我们增加一些搜索功能:
1 | search_fields = ['question'] |
最后,因为Poll对象有日期,因此日期的降序排列会更方便。增加下面这行:
1 | date_hierarchy = 'pub_date' |
注意改动列表给了你一个页码。默认情况下每页显示100条记录。改动列表分页,搜索框,过滤器,时间层次结构和列排列都像预期中预期的那样工作。
九、定制管理页面的外观和感觉
很明显,在每个管理页面的顶部有个“Django administration”是很荒唐的。实际上这是放置文本的地方。
但是,使用Django的模板系统很容易改变这个。Django管理系统是由Django自己支持的,它的接口也是Django自己的模板系统。
打开你的设置文件(mysite/settings.py)查看TEMPLATE_DIRS设置。TEMPLATE_DIRS是一个用来检测合适载入Django模板的系统文件目录的元组。它是一个搜索路径。
默认情况下,TEMPLATE_DIRS是空的,因此,让我们给它增加一行告诉Django我们的模板在什么地方:
1 | TEMPLATE_DIRS = ( |
2 | '/home/my_username/mytemplates', # Change this to your own directory. |
3 | ) |
(Django源代码文件在哪?:如果找你系统上的Django的源文件有困难,运行下面的命令:
1 | python -c " |
2 | import sys |
3 | sys.path = sys.path[1:] |
4 | import django |
5 | print(django.__path__)" |
这个模 板文件包含许多像{% 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开始公共调查的视图。
教程2结束!更多推荐
- · Elasticsearch复杂数据类型终极指南:从入门到精通
- · 终极指南:Flink SQL连接器版本管理从混乱到有序的升级之路
- · 如何快速搭建Neon无服务器PostgreSQL:面向初学者的完整指南
902
0
0
- 0
扫一扫分享内容
分享
顶部















所有评论(0)