Django学习

来源:互联网 发布:淘宝大学生认证 编辑:程序博客网 时间:2024/05/16 14:05

一、参考资料

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监听所有的网络接口,因此其他电脑就能连接到。


Django学习笔记(2):从一个简单的demo开始深入

一、简单的小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="<html><body>现在时刻:%s.</body></html>" %now10     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("<p>i am beginman </p>")3 response.write("<p>coding for fun! </p>")

其他具体信息见《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_datetime3 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),#或者限制最大允许995 )

然后我们在编写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="<html><body>现在时刻:%s.</body></html>" %now10     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="<html><body>In %s hours it will be %s.</body></html>" %(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学习笔记(3):Django模板系统(上)

一、什么是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-------------------------<django.template.Template object at 0x0154541B4>

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:访问字典键值

1

3.2:访问对象的属性

1

3.3:自定义类的应用 
1

3.4:调用对象的方法

1

注意:在Django的模板系统中,应用于模板变量时,方法的调用不能带圆括号,也无法给方法传参数,即:你只能调用不带圆括号的无参的方法

3.5:访问列表序列

1

注意:不允许使用负数列表索引

4、处理无效的变量

默认情况下,如果一个模板变量不存在,则模板系统会把他展示为空字符串

三、小结

本节所学的知识点:1.对Django模板的认识、2.掌握了如何模板的基本使用、3.模板变量技巧性基础掌握

Django学习笔记(4):Django模板系统(中)

一、Django模板的组织形式

在上一节中说的标签、模板变量,或许还没一个笼统的定义。这一节着重学习Django模板系统内置的模板标签和过滤器。首先看这个例子:

复制代码
 1 <html> 2 <head><title>标题</title></head> 3 <body> 4 <p>Dear {{ person_name }},</p> 5 <p>Thanks for placing an order from {{ company }}. It's scheduled to 6 ship on {{ ship_date|date:"F j, Y" }}.</p> 7 <p>Here are the items you've ordered:</p> 8 <ul> 9 {% for item in item_list %}10 <li>{{ item }}</li>11 {% endfor %}12 </ul>13 {% if ordered_warranty %}14 <p>Your warranty information will be included in the packaging.</p>15 {% endif %}16 <p>Sincerely,<br />{{ company }}</p>17 </body>18 </html>
复制代码

其中:{%xxx%}是模板标签;{{eee}}是模板变量,{{eee|jjj:...}}是过滤器形式

Django模板是一个string文本,它用来分离一个文档的展现和数据模板定义了placeholder和表示多种逻辑的tags来规定文档如何展现通常模板用来输出HTML,但是Django模板也能生成其它基于文本的形式

二、常用的模板标签

1.if/else

1 {%if today_is_weekend%}2     <p>Welcome~</p>3 {%else%}4     <p>NO!</p>5 {%endif%}
?
<span style="color: #ff0000;">Python的真值:</span>
空列表[]、空元祖()、空字典{}、空字符串"",零0、None 都为假
其他都是真值

{% if %}还可以与and、or、not一起使用,判断一个或多个变量,或者取反(not)

注意:
1.不允许同时使用and、or
2.不支持圆括号来组合比较操作
3.没有{%elif%}标签
4.每一个{%if%}标签要对应{%endif%}(中间没空格)关闭标签,否则django会抛出TemplateSyntaxError。

2.for

1 <ul>2 {%for person in Person_list%}3     <li>{{person.name}}</li>4 {%endfor%}5 </ul>

注意:
1.我们也能够嵌套for
2.Django不支持退出循环,不支持continue
3.{%for%}标签内置了一个forloop模板变量,它含有一些属性提供循环的信息:

复制代码
1.forloop.counter表示循环的次数,它从1开始计数,第一次循环设为12.forloop.counter0类似于forloop.counter,但它是从0开始计数,第一次循环设为03.forloop.revcounter表示循环中剩下的items数量,第一次循环时设为items总数,最后一次设为14.forloop.revcounter0类似于forloop.revcounter,但它是表示的数量少一个,即最后一次循环时设为05.orloop.first当第一次循环时值为True,在特别情况下很有用:----------------------------------------------------------------------------{% for object in objects %}    {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}    {{ object }}    </li>{% endfor %}----------------------------------------------------------------------------6.forloop.last当最后一次循环时值为True7.forloop.parentloop在嵌套循环中表示父循环的forloop:
复制代码

3.ifequal/ifnotequal

{% ifequal %}比较两个值,如果相等,则显示{% ifequal %}和{% endifequal %}之间的所有内容:

1 {% ifequal a b %}2     <h1>Welcome!a and b</h1>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学习笔记(5):Django模板系统(下)

一、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="<html><body>现在时刻:%s.</body></html>" %now10 #    return HttpResponse(html)11 12 #现在使用django模板来修改该视图函数13 def current_datetime(request): 14     now=datetime.datetime.now()15     t=Template('<html><body>现在时刻是:{{current_date}}</body></html>')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 Time4 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="<html><body>现在时刻:%s.</body></html>" %now11 #    return HttpResponse(html)12 13 #使用django模板来修改该视图函数14 #def current_datetime(request): 15 #    now=datetime.datetime.now()16 #    t=Template('<html><body>现在时刻是:{{current_date}}</body></html>')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 <html><body>It is now {{ current_date }}.</body></html>  

创建了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 #import2 import datetime3 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仅仅是一段字符串,如下:

1 <p>aaa</p>

则,在浏览器中输出:

注意:

如果被引入的模板中包含任何的模板代码,如标签和变量等,它将用父模板的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--BeginMan</h1>10 {%block content%}{%endblock%}11 {%block footer%}12 <hr />13 <p style='color:#ccc'>Thanks for visiting my site</p>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     aaa7 {%endblock%}8 </body>
复制代码

在浏览器中显示效果如下:


[current_datetime.html]

[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学习笔记(6):数据建模(上)

一、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.    }}
复制代码

下面是一些数据库配置清单:

数据库设置适配器PostgreSQLpostgresql(1.x版本)/postgresql_psycopg2(2.x版本)psycopgMySQLmysqlMySQLdbSQLitesqlite3Python2.5内建或pysqliteMicrosoft Serverado_mssqladodbapiOracleoraclecx_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需要知道用哪个配置文件来获得数据库连接信息)

1

如果没显示错误,则说明数据库配置正确,如果出错,则查阅django book 出错类型

三、从一个小demo慢慢深入

1.建立app

注意:如果使用了Django的数据库层,必须创建一个app,创建app命令并显示出来app目录下的文件:

2

2.定义模型

打开models.py,编辑如下:

复制代码
#coding=utf-8from django.db import modelsclass 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

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 语句

4

注意,sqlall命令并没有在数据库中真正创建数据表,而是打印出来,我们可以使用manage.py syncdb 命令去创建

5


Django学习笔记(7):数据建模(下)

一、数据访问

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.数据显示(这里显示所有)

1

但是并没有显示我们想要的结果,这是因为我们在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_publisherWhere name='BeginMan' AND age='22' 

看起来比sql 语句简便多了。

另外还有如__contains(相当于LIKE)、startswith、endswith、range等。这些在后期将会涉及到。

三、获得单个对象

使用get()方法获得单个对象

>>>Publisher.objects.get(name='BeginMan')>>><Publisher:BeginMan>返回的是单个对象,而不是列表[<Publisher:BeginMan>]

如果结果是多个对象,则会抛出异常;如果没有查询到也会抛出异常

四、数据排序

使用order_by()排序 

Publisher.objects.order_by('age')相当于sql下:select * from book_PublisherOrder 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方法,注意删除的不可恢复,当然我们可以使用假删除,只是把它隐藏。这一点在后面会涉及到。


原创粉丝点击