实战Django:官方实例Part2
我们接着Part1部分往下讲.我们在part1中启动服务器后,并没有在管理页面中发现新添加的Polls应用,怎么办捏?
7.在管理界面中显示Question
只要注册一下这个应用就可以了。编辑polls/admin.py 文件,让它变成下面这个样子:
polls/admin.py:
from django.contrib import admin
from polls.models import Question admin.site.register(Question)
这样Django就知道应该把Polls应用的管理功能也加到管理界面中,重新刷新一下浏览器,可以看到页面变成下面这样:
8.添加内容
点击Questions链接,进入Polls的管理页面:
现在什么都没有,点击右上角的”增加question“来添加一项:
在Question text后面输入:”What’s up?”,然后依此点击“今天”和“现在”两个链接,再点保存按钮,这一项就添加好了。
注意观察页面上的三个按钮,分别代表不同的操作:
”保存并增加另一个“,是在做保存动作之后,进入添加下一个的操作;
”保存并继续编辑“,是在做保存动作之后,停留在当前项的编辑页面;
”保存“,则是在做保存动作之后,回到Questions的列表显示页面;
9.优化显示
等等,怎么显示的是“Question object”?这多别扭啊!直接显示”What's Up?“多好?
我们来改一下,编辑polls/models.py文件,给两个Class分别加上”__str__() “方法:
polls/models.py :
from django.db import models class Question(models.Model):
# ...
def __str__(self): # __unicode__ on Python 2
return self.question_text class Choice(models.Model):
# ...
def __str__(self): # __unicode__ on Python 2
return self.choice_text
刷新一下浏览器,这下,顺眼多了吧?
10.定制管理表单
上面这个新增Question的页面样式是不是一成不变的呢?
事实上,Django给我们准备了丰富的定制手段,比如我们要把发布日期和Question text的顺序调换一下,就这么做:
编辑polls/admin.py 文件,把它变成下面这样:
polls/admin.py :
from django.contrib import admin
from polls.models import Question class QuestionAdmin(admin.ModelAdmin):
fields = ['pub_date', 'question_text'] admin.site.register(Question, QuestionAdmin)
刷新一下浏览器,编辑页面变成了这样:
当你只有两个字段的时候,谁先谁后其实无关紧要,但当字段数量变成十几个,甚至几十个的时候,字段的顺序就变得重要起来了。
讲到”大量字段“这个话题的时候,我们可能会用到”把字段分组“这个技巧,
再来编辑polls/admin.py 文件,把它变成下面这样:
polls/admin.py :
from django.contrib import admin
from polls.models import Question class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
] admin.site.register(Question, QuestionAdmin)
刷新一下浏览器,我们的编辑页面变成了这样:
继续延伸这个话题,如果我们的表单很长,这时我们可能会想到要将某些字段”折叠“起来,那么,酱紫做:
编辑polls/admin.py 文件,我们给”Date information“把加入一个'collapse'的样式:
polls/admin.py :
from django.contrib import admin
from polls.models import Question class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
] admin.site.register(Question, QuestionAdmin)
页面就变成了:
只有当你点击图中的”显示“链接时,才可以进行日期信息的编辑。
11.添加关联对象
我们的投票应用还少了一部分:投票的选项还没加到管理界面中来。
要实现这个其实很简单,我们有两种方式。
第一种方式是在admin.py中注册Choice,以便让它显示到管理界面中。
编辑polls/admin.py:
from django.contrib import admin
from polls.models import Choice, Question
# ...
admin.site.register(Choice)
这样Choice就被添加到管理界面中来了:
点击Choices后边的”增加“按钮:
在这个”增加choice“界面中,我们可以在”Question“后边选择已经添加好的问题,然后逐个输入对应的选项——通常每一个投票会有好几个选项可供选择。
好了,问题来了,这样的方式是够简单了,但当你一次性添加好多内容的时候,你每添加一项choice都要在Question后面重新选择问题,内容一多,这就成了件苦差使。有没有更简便的方法?
我们来看第二种方式。
编辑polls/admin.py,移除”admin.site.register(Choice)“这一行,然后添加内容:
polls/admin.py:
from django.contrib import admin
from polls.models import Choice, Question class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3 class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline] admin.site.register(Question, QuestionAdmin)
这等于是在告诉Django,Choice这个对象我们要在Question界面中编辑,默认情况下,一个Question下配上3个Choice,来看下具体的效果吧:
当我们要为一个Question配4个Choice怎么办?很简单,点击上图下方的”添加另一个Choice“链接就行。
还有一个小问题,这样的显示方式,也太占地方了!能不能让布局简洁些?
我们只要改动一个地方,编辑polls/admin.py,改动ChoiceInline这一行:
polls/admin.py:
class ChoiceInline(admin.TabularInline):
#...
把显示样式由StackedInline改为TabularInline。看下效果:
怎么样,紧凑多了吧?
12.改进
我们来看一下那个显示所有Question的列表页面,如下图所示,它只显示了Question这一个字段,有没有可能让显示的字段更多一些呢?
我们可以使用list_display这个选项来实现,编辑polls/admin.py,加上一行:
polls/admin.py :
class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ('question_text', 'pub_date')
看一下,效果出来了:
我们希望看到更多的信息,比如,这个Question是否最近发布的。我们可以在模型中添加一个叫“was_published_recently”的字段来实现它。
编辑polls/models.py,让它变成:
polls/models.py:
import datetime from django.db import models
from django.utils import timezone class Question(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
编辑polls/admin.py,作如下改动:
polls/admin.py :
class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ('question_text', 'pub_date', 'was_published_recently')
看下效果:
我们可以点击每一栏位的标题对其进行排序操作——除了'was_published_recently ?'这一栏,因为这个字段并非数据库自身的字段,而是我们“造”出来的。
不过我们也有办法让它参与排序,并且改进一下显示的方式。
编辑polls/models.py,让它变成下面这个样子:
polls/models.py:
class Question(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?'
刷新一下浏览器:
现在,'was_published_recently ?'这一栏也可以参与排序了,它用来排序的字段是“pub_date”。
Django的admin模块还给我们提供了过滤器的功能,我们可以利用list_filter语句来给“pub_date”字段添加一个过滤器。
编辑polls/admin.py,在QuestionAdmin下添加一行:
polls/admin.py :
list_filter = ['pub_date']
我们可以看到,右侧多了一个叫”过滤器“的侧边栏,你可以使用”今天“、”过去7天“、”本月“、”今年“等条件来对当前显示内容进行过滤。
如果内容一多,我们想快速定位某一个投票项怎么办?
我们可以很方便地添加一个搜索功能。
编辑polls/admin.py,在QuestionAdmin下添加一行:
polls/admin.py :
search_fields = ['question_text']
在列表上方多出了一个搜索文本框,就是这么简单。
13.定制管理页面外观
每个管理页面的顶部都挂着”Django管理“有时看起来很傻。不过你放心,这个是可以替换的。
在我们的项目文件夹(最顶层的mysite文件夹)中建立一个叫templates的文件夹,这样我们的项目文件夹的结构就变成下面这样:
mysite/
manage.py
mysite/
polls/
templates/
我们需要修改一下mysite/settings.py文件,在页面底部加入一行:
mysite/settings.py:
TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')]
然后在templates文件夹下建立一个admin文件夹,并从Django源代码包的django/contrib/admin/templates文件夹下复制一个叫base_site.html的文件到admin文件夹下。
注:电脑里装有everything的童鞋,可以快速搜索一下base_site.html文件。
实在找不到这个文件的,就按照下面的代码新建一个:
{% extends "admin/base.html" %} {% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %} {% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1>
{% endblock %} {% block nav-global %}{% endblock %}
把第四行改为:
<h1 id="site-name"><a href="{% url 'admin:index' %}">投票管理</a></h1>
由于我们在文档中使用了中文,所以这个html文件要储存为”utf-8”的编码——你可以用emeditor之类的文本编辑器快速地实现这一点。不会改编码的童鞋,就先用一个英文名字来代替“投票管理”吧。
我们还可以修改整个后台的索引页,用上面的方法从Django源代码包中复制admin/index.html文件过来,然后进行编辑,具体的方法不再详述。
不要被这里的模板语言吓倒,我们会在Part3中手把手教你如何搞定模板。
【未完待续】
本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
作者:舍得
首发:舍得学苑@博客园
实战Django:官方实例Part2的更多相关文章
- 实战Django:官方实例Part1
[写在前面] 撰写这个实战系列的Django文章,是很久之前就有的想法,问题是手头实例太少,一旦开讲,恐有"无米下锅"之忧. 随着对Django学习的深入,渐渐有了些心得,把这些心 ...
- 实战Django:简易博客Part1
舍得学习新技能的时候,通常不喜欢傻读书--捧着一本阐述该项技能的书籍,然后傻看,一路看下来,脑子里塞满了新的概念.知识点,头是越来越大,但技能却几乎没掌握半分. 多年来,舍得养成了用做实例来学习新技能 ...
- 实战Django:官方实例Part6
我们终于迎来了官方实例的最后一个Part.在这一节中,舍得要向大家介绍Django的静态文件管理. 现在,我们要往这个投票应用里面添加一个CSS样式表和一张图片. 一个完整的网页文件,除了html文档 ...
- 微软官方实例 RazorPagesMovie 在 asp.net core 2.1 版本下的实战
微软官方实例 RazorPagesMovie 在 asp.net core 2.1 版本下的实战 友情提示: 操作系统: MacOS 10.13.5 dotnet core: version 2.1. ...
- 对《[Unity官方实例教程 秘密行动] Unity官方教程《秘密行动》(十二) 角色移动》的一些笔记和个人补充,解决角色在地形上移动时穿透问题。
这里素材全是网上找的. 教程看这里: [Unity官方实例教程 秘密行动] Unity官方教程<秘密行动>(九) 角色初始设定 一.模型设置: 1.首先设置模型的动作无限循环. 不设置的话 ...
- Android实例-Delphi开发蓝牙官方实例解析(XE10+小米2+小米5)
相关资料:1.http://blog.csdn.net/laorenshen/article/details/411498032.http://www.cnblogs.com/findumars/p/ ...
- 微信应用号开发知识贮备之altjs官方实例初探
天地会珠海分舵注:随着微信应用号的呼之欲出,相信新一轮的APP变革即将发生.从获得微信应用号邀请的业内人士发出来的一张开发工具源码截图可以看到,reacjs及其相应的FLUX框架altjs很有可能会成 ...
- 源于《Unity官方实例教程 “Space Shooter”》思路分析及相应扩展
教程来源于:Unity官方实例教程 Space Shooter(一)-(五) http://www.jianshu.com/p/8cc3a2109d3b 一.经验总结 教程中步骤清晰,并且 ...
- 超具体Windows版本号编译执行React Native官方实例UIExplorer项目(多图慎入)
),React Native技术交流4群(458982758).请不要反复加群! 欢迎各位大牛,React Native技术爱好者加入交流!同一时候博客右側欢迎微信扫描关注订阅号,移动技术干货,精彩文 ...
随机推荐
- Hibernate高级查询QBC条件设置——Restrictions用法 引自:http://www.cnblogs.com/evon168/archive/2010/10/29/1863059.html
方法说明 方法 说明 Restrictions.eq = Restrictions.allEq 利用Map来进行多个等于的限制 Restrictions.gt > Restrictions.ge ...
- [ CodeVS冲杯之路 ] P1053
不充钱,你怎么AC? 题目:http://codevs.cn/problem/1053/ 直接扫一遍串,把字母对应的 ascii 码直接做数组下标,交给数组统计 最后查询一遍数组的 'a'-'z' , ...
- Unity球形插值Slerp解析
Unity球形插值,官方有个太阳升降的例子: http://docs.unity3d.com/ScriptReference/Vector3.Slerp.html 一开始主观认为这个球形插值Slerp ...
- matlab 小波变换
MATLAB小波变换指令及其功能介绍 1 一维小波变换的 Matlab 实现 (1) dwt函数 功能:一维离散小波变换 格式:[cA,cD]=dwt(X,'wname') [cA,cD]=dwt(X ...
- AX2012全新的批处理方式
AX2009 的批处理操作我们是通过RunBaseBatch framework,我们所要做的事情就是继承RunBaseBatch class,实现里面该实现的方法来执行批处理. AX2012 的批处 ...
- Android基础总结(1)
1.Android开发的特点 四大组件:活动(Activity).服务(Service).广播接收器(Broadcast Receiver).内容提供器(Content Provider).其中活动是 ...
- typedef 与define 的区别
typedef和#define的用法与区别 typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译 ...
- pb中打开窗口并传递参数
try long ll_result; ll_result=1;openwithparm(w_sb_order,UserCode);catch(RuntimeError er) errorMsg=e ...
- oracle学习系列之三 (约束)
主键约束:外键约束:唯一性约束:检查约束:默认值约束 -——————五大约束 一. 主键约束: --创建表的主键约束 create table student (student_id number ...
- sql基础查询语句
数据库文件百度云地址:www.pan.baidu.com 脚步:下载博客园文件:select_learn.rar 1.TOP限制返回行数[percent] * from book_info --显示前 ...