一、参考资料
1.《Django Book》
2. Google & Baidu & django官网文档
二、Django简介
1.历史
百度一下.......
2.特点
3.MVC设计模式
关于django的mvc开发模式最大特点是松散结合
四、Django的安装
1.具体安装步骤:
百度一下或者见博客
2.注意
(1).Django需要2.3或更高版本的Python
(2).Linux或Mac OS X系统可能预装了Python
(3).Django主持三种数据库引擎:PostgreSQL/MySQL/SQLite 3
3.检查是否安装成功
如果输入上述命令,成功显示版本信息则说明安装成功。
五、Django初体验
如果使用setup.py工具进行安装Django,则django-admin.py已经加入到了系统路径中,由于我们经常使用,所以建议添加到系统搜索路径中,如果是Windows平台则更改PATH环境变量即可(这一点在安装Python和Django的教程中都有)
1.项目流程
(1).打开DOS,可以手动建立一个文件夹或者输入dos命令(mkdir)
(2).输入django-admin.py startproject mysite 则在当前目录创建一个mysite项目,里面包含的有:
__init__.py:让Python把该目录当成一个开发包(即一组模块)所需的文件
manage.py:一种命令行工具,以多种方式与django项目互动
settings.py:该Django项目的配置工具
urls.py:该Django项目的URL声明
(3).启动Django内置的web服务器
在当前目录下输入manage.py runserver 命令即可启动
(4).浏览器中查看
输入127.0.0.1:8000即可看到 界面"It Worked"
2.更改主机或端口
默认的是8000端口,并只能监听本机连接,如果更改可如下:
还可以更改服务器监听的IP地址,可以让django监听所有的网络接口,因此其他电脑就能连接到。
一、简单的小demo来描述django处理流程
1.建立视图(view)
首先在当前目录中新建一个views.py(视图),然后编辑如下:(其实在后面教程中,这只是我们手动建立的,我们完全可以建立一个app,其中就包含它)(我们也可以先建立url映射,在建立对应的视图函数)
1 #coding=utf-8 2 3 #从django.http模块中导入HttpResponse类[1] 4 from django.http import HttpResponse 5 import datetime 6 7 def current_datetime(request): #[2] 8 now=datetime.datetime.now() 9 html="现在时刻:%s." %now 10 return HttpResponse(html)
注意:这是一段很简单、简陋的例子,具体优化见后面介绍
分析:
[1].HttpResponse类位于django.http模块中,是自己手动创建,与Django自动创建的HttpRequest对象不同,在每一个视图(views)都需要实例化、处理、返回一个HttpResponse对象。
一般情况下,创建一个HttpResponse时,以字符串的形式传递页面内容给HttpResponse构造函数:
1 >>>response=HttpResponse('I am BeginMan! ') 2 >>>response=HttpResponse('HelloWorld',mimetype='text/plain')
如果希望增加内容,则可以把response当做一个类文件对象来使用:
1 response=HttpResponse() 2 response.write("i am beginman
") 3 response.write("coding for fun!
")
其他具体信息见《Django Book》附录内容
[2].在这个(views.py)视图中每一个函数称作视图函数,视图函数都以一个HttpRequest对象为第一个参数,该参数通常命名为request
2.URL映射视图
url就像一座桥梁,通过这个桥梁我们才找到视图中对应的代码,渲染的模板(这一章暂时没有将到模板),而这一切都通过一个叫URLConf(即urls.py)的东东,在我们django-admin.py startproject mysite后,该脚本会自动建立一份URLConf(即urls.py文件),我们可以在settings.py中找到它的真身,如下:
1 。。。。。。 2 ROOT_URLCONF = 'mysite.urls' 3 。。。。。。省略
urls.py打开如下:
1 from django.conf.urls.defaults import * #[1] 2 3 # Uncomment the next two lines to enable the admin: 4 # from django.contrib import admin 5 # admin.autodiscover() 6 7 urlpatterns = patterns('', #[2] 8 # Example: 9 # (r'^mysite/', include('mysite.foo.urls')), 10 11 # Uncomment the admin/doc line below to enable admin documentation: 12 # (r'^admin/doc/', include('django.contrib.admindocs.urls')), 13 14 # Uncomment the next line to enable the admin: 15 # (r'^admin/', include(admin.site.urls)), 16 )
分析:
[1].从django.conf.urls.defaults导入所有对象,其中包括了一个叫做patterns的函数
[2].patterns()函数将处理结果保存到urlpatterns变量中,注意patterns(' ',)有块空白,它的存在就是之前的在浏览器显示的it worked 的作用。
具体URL配置见另一篇博文:"URL常用配置"
我们编辑该文件以展示current_datetime视图:
1 from django.conf.urls.defaults import * 2 from mysite.views import current_datetime 3 4 urlpatterns = patterns('', 5 (r'^time/$',current_datetime) 6 )
patterns函数中的参数其实就是一个元祖,前边是一个正则表达式的,后边是对应的视图函数,(在本demo中)在浏览器中通过输入http://127.0.0.1:8000/time ,Django在URLconf中的所有URL模式中,查找第一个匹配/time/的条目。如果匹配成功,则视图函数返回一个HttpResponse,调用current_datetime这个视图函数,Django转换HttpResponse为一个适合的HTTP response, 以Web page显示出来,(在没有模板定义的情况下)显示输出结果。
至此这一系列Django简单的处理流程就完成了。
二、Django处理请求的工作机制
记住:
1.用manage.py runserver 启动Django服务器时就载入了在同一目录下的settings.py。该文件包含了项目中的配置信息,如前面将的URLConf等,其中最重要的配置就是ROOT_URLCONF,它告诉Django哪个Python模块应该用作本站的URLConf,默认的是urls.py
2.当访问url的时候,Django会根据ROOT_URLCONF的设置来装载URLConf。
3.然后按顺序逐个匹配URLConf里的URLpatterns。如果找到则会调用相关联的视图函数,并把HttpRequest对象作为第一个参数(通常是request)
4.最后该view函数负责返回一个HttpResponse对象,
四、深入一步:动态URL
上面一个简单的例子介绍了动态的内容,接下来深入一下url的映射,实现动态的url。
我们要做到就是在url后输入一些参数,从而实现不同的调用内容(如在url后输入数字(小时)来显示当前时间累加后的时间,如当前时间是6:20,在浏览器中输入....time/plus/3,则显示9:20)的小实例(可参见《Django Book》)
我们可以有三种不同的方法来实现:
第一种:全部写入到url中
1 urlpatterns = patterns('', 2 (r'^time/$',current_datetime), 3 (r'^time/plus/1/$',one_hour_ahead), 4 (r'^time/plus/2/$',two_hour_ahead), 5 (r'^time/plus/3/$',three_hour_ahead), 6 ............................... 7 .................. 8 )
这种不解释,累死写不完。pass
第二种:URL查询字符串的形式,以?来实现,如/time/plus?hours=3。这一种在asp.net中常见的一种方式,但是在django中,它会显得臃肿、低效。pass
第三种:带通配符的URL匹配模式
因为URL模式是一个正则表达式,因此,可以使用正则表达式的技巧和URL配置技巧来实现。具体见另两篇博文:Python零碎知识(5):有关正则表达式和Django总结(1):URL常用配置方法
对于本实例,可以使用 \d+ 来匹配一个或多个数字:
1 urlpatterns = patterns('', 2 (r'^time/$',current_datetime), 3 (r'^time/plus/\d+/$',hours_ahead), 4 (r'^time/plus/(\d{1,2})/$',hours_ahead),#或者限制最大允许99 5 )
然后我们在编写hours_ahead视图函数,整理如下:
1 #coding=utf-8 2 3 #从django.http模块中导入HttpResponse类[1] 4 from django.http import HttpResponse 5 import datetime 6 7 def current_datetime(request): #[2] 8 now=datetime.datetime.now() 9 html="现在时刻:%s." %now 10 return HttpResponse(html) 11 12 def hours_ahead(request,offset): 13 offset=int(offset) 14 dt=datetime.datetime.now()+datetime.timedelta(hours=offset) 15 html="In %s hours it will be %s." %(offset,dt) 16 return HttpResponse(html)
注意:hours_ahead有两个参数,第一个request,之前已经讨论过;第二个参数offset是从匹配的URL里提取出来的,如/time/plus/10,则提取offset是10(注意字符串要int成整数才能相加)
五、小结
主要掌握了:1.url映射基础、2.视图函数、3.Django处理请求的工作机制、4.动态URL思想
一、什么是Django的模板系统
1、Template System(模板系统)是Django中的一系列流程的控制,它来实现页面与代码分离(数据展示与功能逻辑的分离)的状态,达到松散模式。
2、Templates(模板)是一个简单的文本文件,可以生成任意文本格式的如html/xml/csv等。我们可以在之前创建的mysite目录中创建一个templates文件夹进行后面的处理。
3、模板系统背后的哲学:
业务逻辑和表现逻辑相对分开,所以就不能在django模板中直接调用Python代码。
二、模板使用的流程
创建模板对象--->模板渲染--->
1、创建模板对象
使用Template类直接实例化,其中Template类来自django.template模块中
>>> from django.template import Template >>> t=Template('My name is {{name}}') >>>print t ---------------------------output-------------------------
2、渲染模板
2.1:渲染操作流程
一旦创建Template对象之后,可以用context传递数据给它,它是一系列变量和它们值的集合,模板使用它来赋值模板变量标签和执行块标签
context在django里表现为Context类,在django.template模块中
Context类构造是一个可选参数:一个字典映射变量和它们的值
创建一系列Context对象之后,调用Template对象的render()方法并传递Context对象来填充模板
>>>from django,template import Template,Context >>>t=Template("My name is {{name}},I love{{language}}") >>>c=Context({'name':'BeginMan','language':'Python/Js/C#'}) >>>t.render(c) --------------------------------output---------------------------------------------- My name is BeginMan ,I love Python/Js/C#
2.2:同一模板,多个上下文(即:多个渲染)
>>>from django,template import Template,Context >>>t=Template("My name is {{name}},I love{{language}}") >>>c1=Context({'name':'BeginMan','language':'Python/Js/C#'}) >>>t.render(c) >>>c2=Context({'name':'Jack','language':'PHP'}) >>>t.render(c2) >>>c3=Context({'name':'Ben','language':'java'}) >>>t.render(c3)
改进:
>>>t=Template('My name is {{name}}') >>>for name in ('BeginMan','Jack','Ben'): .... print t.render(Context({'name':name}))
3.模板变量的灵活多变
模板系统能够处理复杂的数据结构,如list、dictionary和自定义对象等。在Django模板中遍历复杂的数据结构的关键是句点符合(.), 可访问字典的键值、索引、对象的方法、下面让看看在模板变量中句点符合应用
3.1:访问字典键值
3.2:访问对象的属性
3.4:调用对象的方法
注意:在Django的模板系统中,应用于模板变量时,方法的调用不能带圆括号,也无法给方法传参数,即:你只能调用不带圆括号的无参的方法
3.5:访问列表序列
注意:不允许使用负数列表索引
4、处理无效的变量
默认情况下,如果一个模板变量不存在,则模板系统会把他展示为空字符串
三、小结
本节所学的知识点:1.对Django模板的认识、2.掌握了如何模板的基本使用、3.模板变量技巧性基础掌握
一、Django模板的组织形式
在上一节中说的标签、模板变量,或许还没一个笼统的定义。这一节着重学习Django模板系统内置的模板标签和过滤器。首先看这个例子:
1 2标题 3 4Dear {{ person_name }},
5Thanks for placing an order from {{ company }}. It's scheduled to 6 ship on {{ ship_date|date:"F j, Y" }}.
7Here are the items you've ordered:
8
Your warranty information will be included in the packaging.
15 {% endif %} 16Sincerely,
{{ company }}
其中:{%xxx%}是模板标签;{{eee}}是模板变量,{{eee|jjj:...}}是过滤器形式
Django模板是一个string文本,它用来分离一个文档的展现和数据模板定义了placeholder和表示多种逻辑的tags来规定文档如何展现通常模板用来输出HTML,但是Django模板也能生成其它基于文本的形式
二、常用的模板标签
1.if/else
1 {%if today_is_weekend%} 2Welcome~
3 {%else%} 4NO!
5 {%endif%}
空列表[]、空元祖()、空字典{}、空字符串 "" ,零0、None 都为假
其他都是真值
|
{% if %}还可以与and、or、not一起使用,判断一个或多个变量,或者取反(not)
注意:
1.不允许同时使用and、or
2.不支持圆括号来组合比较操作
3.没有{%elif%}标签
4.每一个{%if%}标签要对应{%endif%}(中间没空格)关闭标签,否则django会抛出TemplateSyntaxError。
2.for
1
注意:
1.我们也能够嵌套for
2.Django不支持退出循环,不支持continue
3.{%for%}标签内置了一个forloop模板变量,它含有一些属性提供循环的信息:
1.forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1 2.forloop.counter0类似于forloop.counter,但它是从0开始计数,第一次循环设为0 3.forloop.revcounter表示循环中剩下的items数量,第一次循环时设为items总数,最后一次设为1 4.forloop.revcounter0类似于forloop.revcounter,但它是表示的数量少一个,即最后一次循环时设为0 5.orloop.first当第一次循环时值为True,在特别情况下很有用: ---------------------------------------------------------------------------- {% for object in objects %} {% if forloop.first %}
3.ifequal/ifnotequal
{% ifequal %}比较两个值,如果相等,则显示{% ifequal %}和{% endifequal %}之间的所有内容:
1 {% ifequal a b %} 2Welcome!a and b
3 {% endifequal %}
注意:
1.{% ifequal %}标签支持{% else %},这一点不再累述
2.strings,integers和小数都可以作为{% ifequal %}的参数
3.其它的Python类型,如字典、列表或booleans不能硬编码在{% ifequal %}里面
4.如果你需要测试某个变量是true或false,用{% if %}即可
4.block
定义了一个被子模块覆盖的区块,在模板继承知识点可深入
5.comment
模板引擎会忽略掉{%comment%}...{%endcomment%}之间的内容
6.extends
标记当前模板扩展一个父模板
其他的模板标签可以在以后的章节中详细学习,也可在django 官方文档中查阅。
三、模板注释
Django模板语言允许注释{# #},模板渲染时注释不会输出,一个注释不能分成多行
1 {# This is a comment #}
四、过滤器
1.过滤器简介:
(1):模板过滤器是变量显示前转换它们的值的方式,通过 (|)管道来申请一个过滤器,如姓名转换成小写:
1 {{ name|lower }}
(2):过滤器可以串成链,即一个过滤器的结果可以传向下一个
1 {{ my_text|escape|linebreaks }}
(3):有些过滤器需要参数,过滤器参数一直使用双引号,如显示bio标量的前30个字,
1 {{ bio|truncatewords:"30" }}
2.常用的过滤器
这里我推荐二篇博文,里面讲解十分详细:
http://doudoubear11.blog.163.com/blog/static/301262432011618103643135/
http://blog.csdn.net/yima1006/article/details/7201199
一、Django模板在视图中使用
1.从小的demo开始入手:
上一节,我们使用模板系统,都是在命令行中使用,在实际开发中,我们往往用在视图里。先看一个简单的例子(在djangobook书中的例子,或之前学习笔记中的例子基础上修改)。
1 #coding=utf-8 2 from django.http import HttpResponse 3 import datetime 4 from django.template import Template,Context #记住导入 5 6 #原先的视图函数 7 #def current_datetime(request): #[2] 8 # now=datetime.datetime.now() 9 # html="现在时刻:%s." %now 10 # return HttpResponse(html) 11 12 #现在使用django模板来修改该视图函数 13 def current_datetime(request): 14 now=datetime.datetime.now() 15 t=Template('现在时刻是:{{current_date}}') 16 c=Context({'current_date':now}) 17 html=t.render(c) 18 return HttpResponse(html)
但是模板仍然嵌套在Python代码里面,我们可以使用django强大的API来从硬盘中载入模板,从而减少调用模板和模板本身的冗余。
2.载入模板
载入模板的流程:
(1):建立模板目录和模板文件,建议在mysite目录下,新建一个templates目录,里面放置模板文件,如.html/.csv等
(2):设置settings.py中的TEMPLATE_DIRS,该设置告诉django的模板加载机制在哪里查找模板。
1 TEMPLATE_DIRS = ( 2 '/home/django/mysite/templates', 3 )
1 最好把时区、语言也设置下: 2 #TIME_ZONE = 'America/Chicago' 3 TIME_ZONE = 'CCT' #时区设置为 China Coastal Time 4 5 #LANGUAGE_CODE = 'en-us' 6 LANGUAGE_CODE = 'zh-cn' #语言设置为中文简体,admin后台显示语言及form表单验证信息提示使用
注意:
[1]:你可以指定任何目录,只要那个目录下的目录和模板对于你的Web服务器运行时的用户是可读的
如果你找不到一个放置模板的位置,我们推荐你在Django工程目录下创建一个templates目录
[2]:不要忘了模板目录最后的逗号,Python需要逗号来区分单元素元组和括号括起来的语句,如果你想避免这个错误,可以用列表来替代元组,单元素列表不需要结尾的逗号;元组比列表略微高效,所以我们推荐使用元组
[3]:使用绝对路径很简单,如果你想更灵活和松耦合,你可利用Django的settings文件是简单的Python代码
这点来动态构建TEMPLATE_DIRS内容,例如:
1 import os.path 2 3 TEMPLATE_DIRS = ( 4 os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'), 5 )
Python内部变量 __file__被自动设置为代码所在的Python模块文件名
3.修改视图函数
1 #coding=utf-8 2 from django.http import HttpResponse 3 import datetime 4 from django.template import Template,Context #记住导入 5 from django.template.loader import get_template #记得导入 6 7 #原先的视图函数 8 #def current_datetime(request): #[2] 9 # now=datetime.datetime.now() 10 # html="现在时刻:%s." %now 11 # return HttpResponse(html) 12 13 #使用django模板来修改该视图函数 14 #def current_datetime(request): 15 # now=datetime.datetime.now() 16 # t=Template('现在时刻是:{{current_date}}') 17 # c=Context({'current_date':now}) 18 # html=t.render(c) 19 # return HttpResponse(html) 20 21 #现在使用加载模板来修改该视图函数 22 def current_datetime(request): 23 now=datetime.datetime.now() 24 t=get_template('current_datetime.html') 25 c=Context({'current_date':now}) 26 html=t.render(c) 27 return HttpResponse(html)
注意:
(1):使用了函数 django.template.loader.get_template().加载模板文件,该get_template()函数以模板名称为参数,在文件系统中找处模块的位置,打开文件并返回一个编译好的Template对象
4.在模板目录下创建模块文件
1 It is now {{ current_date }}.
创建了current_datetime.html文件,并将视图函数中的now,填充模板变量{{current_date}}.
在我们所有配置完成之后(如:TEMPLATE_DIRS、TIME_ZONE = 'CCT' 、LANGUAGE_CODE = 'zh-cn')等,在浏览器中打开,我们可以看到解析后的页面显示如下:
二、Django高效的工作
1.render_to_response() 优化:
Django提供了一个捷径来使用一行代码完成载入模板,填充Context,渲染模板,返回HttpResponse对象的工作这就是render_to_response(),它在django.shortcuts模块下大部分情况下,你都会使用render_to_response()而不是手动完成上述的事情
1 from django.shortcuts import render_to_response #import 2 import datetime 3 4 #使用render_to_response优化处理 5 def current_datetime(request): 6 now=datetime.datetime.now() 7 return render_to_response('current_datetime.html',{"current_date":now})
(1):我们不在import get_template,Template,Context或者HttpResponse相反,我们import django.shortcuts.render_to_response,import datetime仍然存在.
(2):render_to_response()的第一个参数应该是使用的模板名,对应到模板目录的相对路径,第二个参数如果有的话应该是一个用来创建Context的字典,如果不提供第二个参数,render_to_response()将使用一个空的字典。
(3):render_to_response返回HttpResponse对象,所以我们return之。
2.locals()小技巧
像上面的,计算一些值后存储在变量中(例如now)并传递给模板懒程序员可能会觉得有点繁琐,既要给临时变量取名又要给模板变量取名这不仅仅是冗余,这是过度输入如果你很懒或者你想保持代码整洁,使用Python内建的locals()方法
locals()返回一个包含当前作用域里面的所有变量和它们的值的字典,上面的代码可以重写:
1 def current_datetime(request): 2 # now=datetime.datetime.now() 3 current_date=datetime.datetime.now() 4 return render_to_response('current_datetime.html',locals())
这里我们传递locals()的值而不是手动指定context字典,locals()包含了所有定义在当前方法的变量而且,我们把now变量重命名为current_date,因为模板需要的是这个变量名这个例子中locals()不会给你太大改善,但这个技术可以帮你少敲键盘。
使用locals()需要注意的是它包含了所有当前变量,可能包括比你的模板想访问的更多的变量上面的例子中,locals()也包括request变量,这依赖于你的程序。
最后要注意的是locals()导致了一点点开销,因为Python不得不动态创建字典,如果你手动指定context字典则可以避免这项开销。
3.get_template()中使用子目录
把所有模板放在一个目录下可能会让事情变得难以掌握,推荐把一些模板放在模板目录下的子目录里,如果我们方法,则只需要调用get_template()时,在模板名前面添加子目录名和斜线即可,如下:
1 def current_datetime(request): 2 current_date=datetime.datetime.now() 3 # t=get_template("date/current_datetime.html") 4 return render_to_response('date/current_datetime.html',locals())
注意:
(1):由于render_to_response()只是对get_template()的简单封装,可以对render_to_response的第一个参数做同样的处理。
(2):对于子目录树的深度没有限制
4.include模板标签
我们已经学习了模板载入机制,我们要介绍一个利用这个机制的内建标签:{% include %}
这个标签允许你引入另一个模板的内容,标签的参数是你想引入的模板的名字,名字可以是变量,也可以是单引号或双引号表示的string。
单双引号都可:
1 {% include 'nav.html' %} 2 {% include "nav.html" %}
下面的例子引入了includes/nav.html模板:
1 {% include 'includes/nav.html' %}
下面的例子引入了一个名字存在于template_name变量中的模板:
1 {% include template_name %}
和get_template()一样,请求的模板名前面会加上TEMPLATE_DIRS,在settings.py 中之前已经设置了:
1 TEMPLATE_DIRS = ( 2 os.path.join(os.path.dirname(__file__),'templates').replace('\\','/'), 3 )
则,include引用模板必须在该目录下,如templates目录下,这里我们引入hello.html
1 <h3> Is is now {{current_date}}h3> 2 <h2 style="color:#F00">{%include "hello.html"%}h2>
hello.html仅仅是一段字符串,如下:
1aaa
如果被引入的模板中包含任何的模板代码,如标签和变量等,它将用父模板的context计算它们
如果给定的模板名不存在,Django将做下面两件事情中的一件:
(1):如果DEBUG设置为True,你将看到一个TemplateDoesNotExist异常的错误页面
(2):如果DEBUG设置为False,标签将什么也不显示
三、模板的继承
我们在使用include的时候,发现很有局限性,Django的模板继承很好地解决了这个问题。流程如下:
1.第一步是建立基本模板(如base.html),即你的子模板的框架
1 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>{%block title %}{%endblock%}title> 6 head> 7 8 <body> 9 <h1>Django--BeginManh1> 10 {%block content%}{%endblock%} 11 {%block footer%} 12 <hr /> 13 <p style='color:#ccc'>Thanks for visiting my sitep> 14 {%endblock%} 15 body> 16 html>
这是一个主模板(基础模板),其他子模板的作用就是重载、继承、添加那些块的内容,{%block%}告诉模板引擎。子模块可以重载这部分。
2.第二步建立子模板
1 ----对current_datetime.html进行修改: 2 <body> 3 {%extends "base.html"%} 4 {%block title%}当前时间{% endblock %} 5 {%block content%} 6 <h3> Is is now {{current_date}}h3> 7 8 {%endblock%} 9 body> 10 html>
1 --------对hello.html进行修改 2 <body> 3 {%extends "base.html"%} 4 {%block title%}HelloWorld{%endblock%} 5 {%block content%} 6 aaa 7 {%endblock%} 8 body>
在浏览器中显示效果如下:
[hello.html]
注意:
(1):{%extends %} 不需要关闭标签,它只是单个出现。当出现{%extends "base.html"%}时,模板引擎会立即装载其父模板。
(2):{%block%}是成对出现的,使用过程中要以{%endblock%}关闭,当遇到{%block%}的时候,用子模板的内容替换这些block。
(3):可使用任意等级的继承,使用继承的常用方式是按以下三个步骤:
[1]:创建base.html模板来掌控你的网站的整体外观,它的内容很少改变
[2]:为你的网站创建base_SECTION.html模板,例如,base_photos.html,base_forum.html这些模板继承base.html并且包括部分专有的风格和设计
[3]:为每个类别的页面创建单独的模板,例如论坛页面或照片图库页面,这些模板拓展相应的模板区域
3、关于模板继承的小提示:
1,如果在模板里使用{% extends %}的话,这个标签必须在所有模板标签的最前面,否则模板继承不工作
2,通常基本模板里的{% block %}越多越好,子模板不必定义所有的父block,钩子越多越好
3,如果你在很多模板里复制代码,很可能你应该把这些代码移动到父模板里
4,如果你需要得到父模板的块内容,{{ block.super }}变量可以帮你完成工作
当你需要给父块添加内容而不是取代它的时候这就很有用
5,不能在同一模板里定义多个同名的{% block %},因为块标签同时在两个地方工作,不仅仅
在子模板中,而且在父模板中也填充内容,如果子模板有两个同名的标签,父模板将不能决定
使用哪个块内容来使用
6,你给{% extends %}传递的模板名同样会被get_template()使用,所以会加上TEMPLATE_DIRS设置
7,大部分情况下,{% extends %}的参数是string,但是也可以是变量,如果知道运行时才知道
父模板的名字,这可以帮助你做一些很cool的动态内容
一、Django的MTV开发模式
在学.net时,我们曾接触过.net的mvc模式,是一种软件架构模式。MVC(Model—View—Controller)
M(Model):数据存储层
V(View):业务逻辑层,显示什么和怎么显示
C(Controller):表现逻辑层,控制访问
Django的MVC模式:
M:数据存取部分,model,如(models.py)
V:显示哪些数据和怎么显示, 由视图(如views.py)和模板(如index.html)处理
C:控制访问视图的部分,通过URLConf设置,如(urls.py)
由于”C”由框架自行处理,在Django中我们更关注的是模型(Model)、模板(Template)、视图(View),故Django也称MTV框架:
M:数据存取层,处理与数据相关的所有事务,如:存取数据、确认有效性、行为定义、数据关系
T:表现层,该层处理与表现相关的事务,如:在页面或其他类型文档中显示
V:业务逻辑层,包含存取模板以及处理模板的相关逻辑,可以把它看作是M和T之间的桥梁
二、Django开发过程中的数据库配置
1、配置处理
要告诉django要用哪些数据库,如何使用。打开settings.py,配置信息如下:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 'NAME': '', # Or path to database file if using sqlite3. 'USER': '', # Not used with sqlite3. 'PASSWORD': '', # Not used with sqlite3. 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. 'PORT': '', # Set to empty string for default. Not used with sqlite3. } }
下面是一些数据库配置清单:
数据库 | 设置 | 适配器 |
PostgreSQL | postgresql(1.x版本)/postgresql_psycopg2(2.x版本) | psycopg |
MySQL | mysql | MySQLdb |
SQLite | sqlite3 | Python2.5内建或pysqlite |
Microsoft Server | ado_mssql | adodbapi |
Oracle | oracle | cx_Oracle |
我这里配置如下:
DATABASES = { 'default': { 'ENGINE': 'sqlite3.', 'NAME': '/mysite/mysite/mydata.db', # 自己起名,自己设置存储的位置 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', } }
2、测试配置
在项目目录中运行manage.py shell命令进入Python交互界面,
---(manage.py shell 启动的Python交互界面与标准Python交互界面的区别:前者通过命令启动,并且告诉了Django使用哪个配置信息[因为在我们所创建目录下启动的],这对于数据库操作很关键,Django需要知道用哪个配置文件来获得数据库连接信息)
如果没显示错误,则说明数据库配置正确,如果出错,则查阅django book 出错类型
三、从一个小demo慢慢深入
1.建立app
注意:如果使用了Django的数据库层,必须创建一个app,创建app命令并显示出来app目录下的文件:
2.定义模型
打开models.py,编辑如下:
#coding=utf-8 from django.db import models class Publisher(models.Model): name=models.CharField(max_length=30) #出版商姓名 address=models.CharField(max_length=50) #地址 tel=models.CharField(max_length=20) #联系方式 website=models.URLField() #网站 class Author(models.Model): salutation=models.CharField(max_length=10)#称呼 first_name=models.CharField(max_length=30)#姓 last_name=models.CharField(max_length=30) #名 email=models.EmailField() #电子邮箱 class Book(models.Model): title=models.CharField(max_length=100) #书名 authors=models.ManyToManyField(Author) #作者(多对多关系) publisher=models.ForeignKey(Publisher) #出版商(一对多关系) publication_date=models.DateField()#出版日期
注意:
(1):老版本的maxlength被新版本替换成了max_length
(2):每一个数据模型都是django.db.models.Model的子类,所以要记得from django.db import models
(3):每个模型相当于单个数据库表(默认情况下,表名是app目录名和类名的小写形式,如”books_publisher”
(4):每个属性相当于是这个表中的一个字段,属性名就是字段名,它的类型相当于数据库的字段类型
(5):Django会自动为每一个模板创建一个叫做id的主键,每一个Django模型都必须有一个单列主键
上面定义的数据建模,可以对应sql,如Author,如果在sql 中建立,则等同如下:
3.模型(model)安装
定义模型之后,要激活这些app,从而激活模型,可以在settings.py中完成激活,修改缺省的MIDDLEWARE_CLASSES (middleware:中间设备,中间件) 和INSTALLED_APPS(installed:安装过的):
#先注释掉这部分 MIDDLEWARE_CLASSES = ( # 'django.middleware.common.CommonMiddleware', # 'django.contrib.sessions.middleware.SessionMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', # 'django.contrib.auth.middleware.AuthenticationMiddleware', # 'django.contrib.messages.middleware.MessageMiddleware', ) ROOT_URLCONF = 'mysite.urls' TEMPLATE_DIRS = ( ) #注释掉这部分,并且把'mysite.books 添加上去(不要忘了带逗号)' INSTALLED_APPS = ( # 'django.contrib.auth', # 'django.contrib.contenttypes', # 'django.contrib.sessions', # 'django.contrib.sites', # 'django.contrib.messages', 'mysite.books', )
4.创建数据库及数据库表
首先验证模型安装成功与否,使用validate命令检查模型语法和逻辑是否正确,如果一切正确则显示 0 errors found
如果没有问题,则运行 manage.py sqlall books 来生成CRETATE TABLE 语句
注意,sqlall命令并没有在数据库中真正创建数据表,而是打印出来,我们可以使用manage.py syncdb 命令去创建
一、数据访问
1.插入、更新数据
插入数据:我们通过新建对象实例来执行插入数据
>>>p=Publisher(name='BeginMan',
..... address='ZhengZhou',
..... tel='2355233',
..... website='http://www.BeginMan.com')
注意,此时我们只是建立一个对象实例,并没有把这个记录保存到(也就是执行Insert)数据库中,就像我们新建一个变但并没有分配内存一样,我们还需要调用对象的save()方法,来实现插入数据的最后一步。
>>>p.save()
更新数据:直接调用对象的save方法
p.name=’LiHong’
p.save()
2.数据显示(这里显示所有)
但是并没有显示我们想要的结果,这是因为我们在models.py建模的时候并没有定义显示。这里我们添加一个方法__str__()到Publisher类中,当实例化的时候,__str__()会告诉Python要如何把对象当字符串使用。
class Publisher(models.Model):
........
def __str___(self):
return self.name
二、选择数据
1.选择所有数据
数据模型类.objects.all()
如Publisher.objects.all(),这里的objects是一个管理器,所有的模型都自动拥有一个objects管理器,objects的all()方法用来返回所有记录。
我们可以在结果显示中看到像是一个列表,但实际上它是一个QuerySet对象,是数据库中一些记录的集合。
2.数据过滤
获得一个数据的子集,使用filter()方法。它相当于sql语句中的where
Publisher.objects.filter(name='BeginMan',age=22)
相当于:
Select
id,name,address,age.tel,website from book_publisher
Where name='BeginMan' AND age='22'
看起来比sql 语句简便多了。
另外还有如__contains(相当于LIKE)、startswith、endswith、range等。这些在后期将会涉及到。
三、获得单个对象
使用get()方法获得单个对象
>>>Publisher.objects.get(name='BeginMan')
>>>
返回的是单个对象,而不是列表[]
如果结果是多个对象,则会抛出异常;如果没有查询到也会抛出异常
四、数据排序
使用order_by()排序
Publisher.objects.order_by('age')
相当于sql下:
select * from book_Publisher
Order By age
注意:
1.可以对任意字段进行排序
2.可以多字段排序
3.可以逆向排序,即在前面加一个减号(如:Publisher.objects.order_by(‘-age’))
4.指定模板的缺省排序方式。
上面每次都要使用order_by()太繁琐,我们可以在指定模型下定义缺省排序方式
class Publisher(models.Model):
......
class Meta:
ordering=['age']
五、限制返回的数据
也就是取出固定数目的记录,如上面所讲的,数据类.objects.all()/filter(xxx) 返回的对象类似列表,但其实是QuerySet对象,我们可以利用下标或切片进行数目的选取,如显示第一个:
>>>Publisher.objects.all()[0]
相当于 Select * from book_publisher order by name limit 1
六、删除对象
删除单个
>>>p=Publisher.objects.get(name='BeginMan')
>>>p.delete()
批量删除
>>>p=Publisher.objects.all()
>>>p.delete()
删除对象使用其delete方法,注意删除的不可恢复,当然我们可以使用假删除,只是把它隐藏。这一点在后面会涉及到。