一步一步学Django.docx
《一步一步学Django.docx》由会员分享,可在线阅读,更多相关《一步一步学Django.docx(74页珍藏版)》请在冰豆网上搜索。
![一步一步学Django.docx](https://file1.bdocx.com/fileroot1/2022-11/22/8e4e9db2-f638-486c-a9bd-c21b711b2ddf/8e4e9db2-f638-486c-a9bd-c21b711b2ddf1.gif)
一步一步学Django
第一讲入门
1开篇
Django是新近出来的Rails方式的web开发框架。
在接触Django之前我接触过其它几种Python下的webframework,但感觉Karrigell是最容易上手的。
不过Django从我个人的感觉上来看,它的功能更强大,社区也很活跃,高手众多,发展也是极为迅速。
3 Django的入门体验
但Django呢?
如果说最简单的web体验Hello,Django!
如何写呢?
决不会象Karrigell那样简单,只从它提供的教程来看,你无法在安装后非常Easy地写出一个Hello,Django!
的例子,因为有一系列的安装和准备工作要做。
那么下面我把我所尝试写最简单的Hello,Django!
的例子写出来。
请注意,我测试时是在WindowsXP环境下进行的。
3.1 安装
pythonsetup.pyinstall
参考文档Djangoinstalled,一般地,Django安装前还需要先安装setuptools包。
可以从PyPI上搜到。
目前最新的版本是0.95版,可以从Django的主页上面下载。
如果你想从老的0.91迁移到最新版本,可以参阅RemovingTheMagic文档。
安装后,建议检查pythoninstalldir/Scripts目录是否在你的PATH环境中,如果不在,建议将这个目录设置到PATH中。
因为如果你采用标准的Python安装方法,那么Django会自动在Scripts目录下安装django-admin.py程序。
这样,一旦你设置了Scripts在PATH中,就可以在命令行下任何目录中执行django-admin.py了。
3.2 生成项目目录
因为Karrigell可直接开发,因此放在哪里都可以。
而Django是一个框架,它有特殊的配置要求,因此一般不需要手工创建目录之类的工作,Django提供了django-admin.py可以做这件事。
为使用django-admin.py,建议将Python的Scripts目录加入到PATH环境变量中去。
django-admin.pystartprojectnewtest
这样就在当前目录下创建了一个newtest目录,进去入可以看到有四个文件:
这个newtest将是我们以后工作的目录,许多讲解都是基于这个目录的。
__init__.py
表示这是一个Python的包
manage.py
提供简单化的django-admin.py命令,特别是可以自动进行DJANGO_SETTINGS_MODULES和PYTHONPATH的处理,而没有这个命令,处理上面环境变量是件麻烦的事情
settings.py它是django的配置文件
uls.pyurl映射处理文件,Django的url映射是url对某个模块方法的映射,目前不能自动完成
在0.91版,django-admin.pystartproject会生成apps目录。
但0.95版之后已经没有了。
虽然django-admin.py为我们生成了许多东西,而且这些东西在以后的开发中你都需要熟悉,但现在我们的目标是最简单的体验,就认为我们不需要知道它们都有什么用吧。
项目创建好了,那么我们可以启动服务器吗?
Django为了开发方便,自带了一个用于开发的webserver。
在0.91版,你需要至少修改一下settings.py中的DATABASE_ENGINE,如果你不改,那么Django会报错。
在0.95版之后,不再需要设置了。
3.3.1 启动webserver:
别急呀,还没看见Hello,Django!
在哪里呢。
是的,我只是想看一看,Django能否启动。
manage.pyrunserver
一旦出现:
Validatingmodels...
0errorsfound.
Startingserveronport8000withsettingsmodule'newtest.settings'.
Gotohttp:
//127.0.0.1:
8000/forDjango.
QuittheserverwithCONTROL-C(Unix)orCTRL-BREAK(Windows).
说明Django真的启来了。
在浏览器中看一下,有一个祝贺页面,说明成功了。
3.3.2更改主机或端口
默认情况下,runserver命令在8000端口启动开发服务器,且只监听本机连接。
要想要更改服务器端口的话,可将端口作为命令行参数传入:
pythonmanage.pyrunserver8080
还可以改变服务器监听的IP地址。
要和其他开发人员共享同一开发站点的话,该功能特别有用。
下面的命令:
pythonmanage.pyrunserver0.0.0.0:
8080
会让Django监听所有网络接口,因此也就让其它电脑可连接到开发服务器了
3.4 增加一个helloworld的app吗?
在Django中绝大多数应用都是以app形式存在的,但一定要加吗?
其实并不一定。
在Django中,每个app就是一个子包,真正调用时需要通过URLDispatch来实现url与模块方法的映射。
这是Django的一大特色,但也是有些麻烦的地方。
不用它,你无法发布一个功能,如果在Django中存在一种缺省的简单映射的方式,这样我想可以大大提高Django的入门体验度。
不过在比较大的项目中,使用app还是一个非常好的方式,它可将项目功能进行分割,以便组织和代码的重用。
因此根据URLDispatch的机制,我们只要保证Django可以在正确的地方找到方法进行调用即可。
那么我们就根本不去创建一个app了。
在newtest目录下建一个文件helloworld.py内容为:
fromdjango.httpimportHttpResponse
defindex(request):
returnHttpResponse("Hello,Django.")
0.95版之后对许多Django模块都做了简化。
具体可参考:
NamespaceSimplification文档。
3.5 修改urls.py
fromdjango.conf.urls.defaultsimport*
urlpatterns=patterns('',
#Example:
#(r'^newtest/',include('newtest.apps.foo.urls.foo')),
(r'^$','newtest.helloworld.index'),
#Uncommentthisforadmin:
#(r'^admin/',include('django.contrib.admin.urls')),
)
上面的r'^$'是为了匹配空串,也就是形如:
http:
//localhost:
8000/。
如果这时webserver已经启动了,那么直接刷新页面就行了。
现在觉得Django是不是简单多了,除了创建一个项目的操作,然后可能要修改两个配置文件。
4 结论
Django本身的确是一种松散的框架组合,它既复杂又简单。
复杂是因为如果你想使用它的自动化的、高级的功能你需要学习很多的东西,而且它的教程一上来就是以这种过于完整的例子进行展示,自然会让你觉得很麻烦。
不过看了我的讲解之后,是不是觉得还是挺简单的。
那么我们就先以无数据库的方式进行下去,一点点地发掘Django的功能特性吧。
第二讲生成一个webform做加法的简单例子
1 引言
随着学习,我们的例子也开始复杂了,下一步我想实现一个简单的web加法器。
界面会是这样:
如何处理页面表格提交的数据,并且会对URLDispatch作更进一步的解释。
2 创建add.py文件
我们先创建一个add.py文件。
(由于我们还没有涉及到Django的模型,因此象add.py这样的东西叫什么呢?
还是称其为View吧。
因为在django中,View是用来显示的,它代替了一般的MVC中的Control的作用,因为Django中不是MVC而是MTV(ModelTemplateView))
fromdjango.httpimportHttpResponse
text="""
+
"""
defindex(request):
ifrequest.POST.has_key('a'):
a=int(request.POST['a'])
b=int(request.POST['b'])
else:
a=0
b=0
returnHttpResponse(text%(a,b,a+b))
请注意action为/add/,在Django中链接后面一般都要有'/',不然有可能得不到POST数据。
有关更详细的关于常见问题可以参阅NewbieMistakes文档。
这里只有一个index方法。
所有在view中的方法第一个参数都会由Django传入request对象,它就是请求数据对象,它是由Django自动生成。
其中有GET和POST属性,分别保存两种不同的提交方式的数据,它们都可以象字典一样工作。
更多关于request的内容参见Requestandresponseobjects文档。
那么我的想法就是:
进入页面后(就是上面的效果),页面上有两个输入文本框,一个是提交按钮,一个是显示结果的文本框。
在两个输入文本框中输入整数,然后点击提交("="号按钮),将返回相同的页面,但结果文本框中将显示两数相加的和。
两个输入文本框分别定义为a和b。
这里的逻辑就是:
先判断POST数据中是否有变量a,如果没有则表示是第一次进入,则a,b初始为0,然后返回页面。
如果有变量a,则计算结果,返回页面。
3 修改urls.py,增加add的url映射。
fromdjango.conf.urls.defaultsimport*
urlpatterns=patterns('',
#Example:
#(r'^testit/',include('newtest.apps.foo.urls.foo')),
(r'^$','newtest.helloworld.index'),
(r'^add/$','newtest.add.index'),
#Uncommentthisforadmin:
#(r'^admin/',include('django.contrib.admin.urls')),
)
4启动server
5在浏览器测试:
http:
//localhost:
8000/add,你会看到和我相似的界面,然后输入整数试一试。
6 补充说明
1.在form中的method="post"。
你当然可以使用get,但是在Django的设计风格中认为,使用POST表示要对数据进行修改,使用GET则只是获取。
2.Django提供了URLDispatch文档,专门讲解有关url映射的东西。
其中有一部分是关于url的正则表达式解析的。
原本我认为象Karrigell中一样,定义在form中的变量会自动映射为方法的参数,但是我错了。
方法中的参数是从url中通过正则表达式解析出来的,或者是在url_conf(即urls.py文件)中指定的。
因此它与Karrigell一点也不一样。
因此,如果你想从POST或GET数据中得到值,那么象我一样去做好了。
使用request.POST或request.GET或还有一个可以“统吃”的方法request.REQUEST,它们是一个字典数据,使用起来也算方便。
从这里我更想了解方法中参数的使用,当然这个例子并没有,有机会再使用吧。
关于正则表达式解析参数在blog和rss中用得是非常多的。
第三讲使用Template的简单例子
1 引言
从上一例我们看到,表格的生成是直接在index()函数中返回的HTML代码,这种混合方式对于大型开发非常不好,下面我们就学习模板的使用。
Django自带有模板系统,但你可以不使用它,只要在return前使用自已喜欢的模板系统进行处理,然后返回即可。
但Django自带的模板系统有很多特点,我不做过多的说明。
我只是想使用它。
现在我的问题就是:
我有一个通讯录数据,我想使用一个表格来显示。
为了方便,我们不需要使用数据库,因此我把它存在view文件中。
2 创建list.py
#coding=utf-8
fromdjango.shortcutsimportrender_to_response
address=[
{'name':
'张三','address':
'地址一'},
{'name':
'李四','address':
'地址二'}
]
defindex(request):
returnrender_to_response('list.html',{'address':
address})
我使用了汉字,并且字符的编码使用了utf-8,请注意,而且以后如果不特别注明,所有的带汉字的文件,包括模板都将使用utf-8编码。
这里使用了一个新方法是render_to_response,它可以直接调用模板并返回生成好的文本。
它接收两个参数,第一个是模板的文件名。
在Django0.91中,模板文件都是以.html结尾的,并且使用时是不带后缀的。
但0.95版本取消了缺省模板后缀的设置,因此模板文件名必须是完整的,不再有默认后缀了。
第二个参数是一个字典,这里只有一个Key,名字是address,它的值是一个字典的列表。
只要注意模板所接收的就是这样的字典和包含字典的列表就行了。
在0.91中render_to_response是在django.core.extensions中的,而到了0.92转变为django.shortcuts。
3 在newtest中创建templates目录:
用来存放模板文件
4 修改settings.py
TEMPLATE_DIRS=(
#Putstringshere,like"/home/html/django_templates".
#Alwaysuseforwardslashes,evenonWindows.
'./templates',
)
如果有多个模板目录,加进去就行了。
Django会按顺序搜索的。
Django还支持在App中定义一个templates目录。
这样Django在启动时会检查所有安装的的App的templates目录,如果存在,则将路径的搜索放在TEMPLATE_DIRS之后。
这样就可以很方便地管理你的模板了。
5 创建templates/list.html
通讯录
姓名 | 地址 |
---|
{%foruserinaddress%}
{{user.name}} | {{user.address}} |
{%endfor%}
生成了一个两列的表格。
在Django模板中{{}}表示引用一个变量,{%%}表示代码调用。
在变量引用中,Django还支持对变量属性的访问,同时它还有一定的策略,详细的建议查看TheDjangotemplatelanguage文档。
这里我也使用了汉字,因此它也需要使用utf-8编码。
这里使用for..in的模板Tag处理。
因此address需要是一个集合。
在我们的View代码中,address为一个list值。
每个list又是一个字典。
因此{{user.name}}和{{user.address}}就是将此字典中的元素取出来。
后面我们将了解更多的模板中的Tag标签的使用。
且你会发现,Django中的Tag很强大,可通过扩展形成庞大的Tag库方便模板的开发。
6 修改urls.py增加了list的url映射。
fromdjango.conf.urls.defaultsimport*
urlpatterns=patterns('',
#Example:
#(r'^testit/',include('newtest.apps.foo.urls.foo')),
(r'^$','newtest.helloworld.index'),
(r'^add/$','newtest.add.index'),
(r'^list/$','newtest.list.index'),
#Uncommentthisforadmin:
#(r'^admin/',include('django.contrib.admin.urls')),
)
7 启动server:
http:
//127.0.0.1:
8000/list,效果如这样:
第四讲生成csv格式文件并下载
1 引言
经过前几节的学习,我想大家应该比较熟悉Django的大致开发流程了:
∙增加view方法
∙增加模板
∙修改urls.py
剩下的就是挖掘Django提供的其它的能力。
在我们还没有进入模型(model)之前还是再看一看外围的东西,再更进一步体验Django吧。
在Django中我看到了一个生成csv格式的文档(OutputtingCSVdynamically),非常好,它没有数据库,正好用来做演示。
现在我的需求就是提供csv格式文件的下载。
我们会在原来list(表格)例子基础上进行演示,步骤就是上面的流程。
2 修改templates/list.html
在文件最后增加:
csv格式下载
它将显示为一个链接,它所指向的链接将用来生成csv文件。
3 在newtest下增加csv_test.py
#coding=utf-8
fromdjango.httpimportHttpResponse
fromdjango.templateimportloader,Context
address=[
('张三','地址一'),
('李四','地址二')
]
defoutput(request,filename):
response=HttpResponse(mimetype='text/csv')
response['Content-Disposition']='attachment;filename=%s.csv'%filename
t=loader.get_template('csv.html')
c=Context({'data':
address,})
response.write(t.render(c))
returnresponse
loader,Context是从django.core.template导入的,而0.95为django.template。
具体可以参考:
NamespaceSimplification文档。
以后类似的地方不再详述。
这里使用的东西多了一些。
这里没有render_to_response了,而是演示了一个完整的从头进行模板解析的处理过程。
为什么需要这样,因为我们需要修改response对象的值,而render_to_response封装了它使得我们无法修改。
从这里我们也可以看到,在调用一个方法时,Django会传入一个request对象,在返回时,你需要将内容写入response,必要时修改它的某些属性。
更详细的建议你参考django所带的request_response文档,里面详细描述了两个对象的内容,并且还可以在交互环境下进行测试,学习非常方便。
response对象也是由Django自动维护的。
具体的内容参见Requestandresponseobjects文档。
这里address不再是字典的列表,而是tuple的列表。
让人高兴的是,Django的模板除了可以处理字典,还可以处理序列,而且可以处理序列中的元素。
一会在模板定义中我们会看到。
这里output()是我们希望Django调用的方法,不再是index()了。
而且它与前面的index()不同,它带了一个参数。
这里主要是想演示url的参数解析。
因此你要注意,这个参数一定是放在url上的。
它表示输出文件名。
response=HttpResponse(mimetype='text/csv')
response['Content-Disposition']='attachment;filename=%s.csv'%filename
这两行是用来处理输出类型和附件的。
它表明返回的是一个csv格式的文件。
t=loader.get_template('csv.html')
c=Context({'data':
address,})
response.write(t.render(c))
这几行就是最原始的模板使用方法。
先通过loader来找到需要的模板,然后生成一个template对象,再生成一个Context对象,它就是一个字典集。
然后t.render(c)这个用来对模板和提供的变量进行合并处理,生成最终的结果。
最后调用response.write()将内容写入。
4 增加templates/csv.html
{%forrowindata%}"{{row.0|addslashes}}","{{row.1|addslashes}}",
{%endfor%}
使用了一个for循环。
这里data与上面的Context的data相对应。
因为data