【updating】python读书笔记-The Django Book2.0(for django1.4)

或者http://docs.30c.org/djangobook2/chapter01/

其他资料:Django1.3 模板标签和过滤器:http://my.oschina.net/dddttttt/blog/304200
 

第一章:介绍Django

框架

使用Python开发Web,最简单,原始和直接的办法是使用CGI标准 
如何工作: 首先做一个Python脚本,输出HTML代码,然后保存成.cgi扩展名的文件,通过浏览器访问此文件。
推荐按顺序阅读第 1-12 章。这些章节构成了如何使用 Django 的基础;读过之后,你就可以搭建由 Django 支撑的网站了。 1-7章是核心课程,8-11章讲述django的高级应用,12章讲述部署相关的知识。 剩下的13-20章,讲述django特有的特点,可以任意顺序阅读。
 
 转到你创建的目录,运行命令django-admin.py startproject mysite。这样会在你的当前目录下创建一个目录。mysite

 
第二章
安装Django1.3-》配置系统变量
 Django 所捆绑的一些附加工具 一定 需要数据库,因此如果选择不使用数据库,你将不能使用那些功能。 (我们将在本书中自始至终强调这些功能) 
----

django-admin.py startproject mysite命令创建一个目录,包含4个文件:

mysite/
    __init__.py
    manage.py
    settings.py
    urls.py

文件如下:

  • __init__.py :让 Python 把该目录当成一个开发包 (即一组模块)所需的文件。 这是一个空文件,一般你不需要修改它。

  • manage.py :一种命令行工具,允许你以多种方式与该 Django 项目进行交互。 键入python manage.py help,看一下它能做什么。 你应当不需要编辑这个文件;在这个目录下生成它纯是为了方便。

  • settings.py :该 Django 项目的设置或配置。 查看并理解这个文件中可用的设置类型及其默认值。

    urls.py:Django项目的URL设置。 可视其为你的django网站的目录。 目前,它是空的。
 
------
django 自带的这个 web 服务器 在同一时间,该服务器目前只能可靠地处理一次单个请求,并且没有进行任何类型的安全审计。 发布站点前,请参阅第 20 章了解如何部署 Django 
-----
修改默认端口

默认情况下, runserver 命令在 8000 端口启动开发服务器,且仅监听本地连接。 要想要更改服务器端口的话,可将端口作为命令行参数传入:

python manage.py runserver 8080

通过指定一个 IP 地址,你可以告诉服务器–允许非本地连接访问。 如果你想和其他开发人员共享同一开发站点的话,该功能特别有用。 `` 0.0.0.0`` 这个 IP 地址,告诉服务器去侦听任意的网络接口。

python manage.py runserver 0.0.0.0:8000
完成这些设置后,你本地网络中的其它计算机就可以在浏览器中访问你的 IP 地址了。比如: http://192.168.1.103:8000/ . (注意,你将需要校阅一下你的网络配置来决定你在本地网络中的IP 地址) Unix用户可以在命令提示符中输入ifconfig来获取以上信息。 使用Windows的用户,请尝试使用 ipconfig 命令。

第三章 视图和URL配置

Hello world视图非常简单。 这些是完整的函数和导入声明,你需要输入到views.py文件:

from django.http import HttpResponse

def hello(request):
    return HttpResponse("Hello world")

我们逐行逐句地分析一遍这段代码:

首先,我们从 django.http 模块导入(import) HttpResponse 类。参阅附录 H 了解更多关于 HttpRequest 和 HttpResponse 的细节。 我们需要导入这些类,因为我们会在后面用到。

接下来,我们定义一个叫做hello 的视图函数

每个视图函数至少要有一个参数,通常被叫作request。 这是一个触发这个视图、包含当前Web请求信息的对象,是类django.http.HttpRequest的一个实例。在这个示例中,我们虽然不用request做任何事情,然而它仍必须是这个视图的第一个参数。

这个函数只有简单的一行代码: 它仅仅返回一个HttpResponse对象,这个对象包含了文本“Hello world”。

URLconf

URLconf 就像是 Django 所支撑网站的目录。它的本质是 URL 模式以及要为该 URL 模式调用的视图函数之间的映射表。 你就是以这种方式告诉 Django,对于这个 URL 调用这段代码,对于那个 URL 调用那段代码。 例如,当用户访问/foo/时,调用视图函数foo_view(),这个视图函数存在于Python模块文件view.py中。
------

默认的URLconf包含了一些被注释起来的Django中常用的功能,仅仅只需去掉这些注释就可以开启这些功能. 下面是URLconf中忽略被注释的行后的实际内容

from django.conf.urls.defaults import *

urlpatterns = patterns('',
)

让我们逐行解释一下代码:

  • 第一行导入django.conf.urls.defaults下的所有模块,它们是Django URLconf的基本构造。 这包含了一个patterns函数。

  • 第二行调用 patterns() 函数并将返回结果保存到 urlpatterns 变量。patterns函数当前只有一个参数—一个空的字符串。 
------------

如果想在URLconf中加入URL和view,只需增加映射URL模式和view功能的Python tuple即可. 这里演示如何添加view中hello功能.

from django.conf.urls.defaults import *#其实只用到了里面的pattern
from mysite.views import hello#这句报错,我修改成去掉了mysite.
urlpatterns = patterns('',
    ('^hello/$', hello),
)#正则表达式

请留意:为了简洁,我们移除了注释代码。 如果你喜欢的话,你可以保留那些行。)

我们做了两处修改。

  • 首先,我们从模块 (在 Python 的 import 语法中, mysite/views.py 转译为 mysite.views ) 中引入了 hello 视图。 (这假设mysite/views.py在你的Python搜索路径上。关于搜索路径的解释,请参照下文。)

  • 接下来,我们为urlpatterns加上一行: (‘^hello/$’, hello), 这行被称作URLpattern,它是一个Python的元组。元组中第一个元素是模式匹配字符串(正则表达式);第二个元素是那个模式将使用的视图函数。

 
简单来说,我们只是告诉 Django,所有指向 URL /hello/ 的请求都应由 hello 这个视图函数来处理。
-------------

正则表达式

正则表达式 (或 regexes ) 是通用的文本模式匹配的方法。 Django URLconfs 允许你 使用任意的正则表达式来做强有力的URL映射,不过通常你实际上可能只需要使用很少的一 部分功能。 这里是一些基本的语法。

符号匹配
. (dot) 任意单一字符
\d 任意一位数字
[A-Z] A 到 Z中任意一个字符(大写)
[a-z] a 到 z中任意一个字符(小写)
[A-Za-z] a 到 z中任意一个字符(不区分大小写)
+ 匹配一个或更多 (例如, \d+ 匹配一个或 多个数字字符)
[^/]+ 一个或多个不为‘/’的字符
? 零个或一个之前的表达式(例如:\d? 匹配零个或一个数字)
* 匹配0个或更多 (例如, \d* 匹配0个 或更多数字字符)
{1,3} 介于一个和三个(包含)之前的表达式(例如,\d{1,3}匹配一个或两个或三个数字)
 
有关正则表达式的更多内容,请访问 http://www.djangoproject.com/r/python/re-module/.
---------

这些敏感信息如果部署到了因特网上的站点就不应该暴露 这些信息。这个“Page not found”页面只会在 调试模式(debug mode) 下 显示。 我们将在以后说明怎么关闭调试模式。

------------
Python工作过程:

所有均开始于setting文件。当你运行python manage.py runserver,脚本将在于manage.py同一个目录下查找名为setting.py的文件。这个文件包含了所有有关这个Django项目的配置信息,均大写: TEMPLATE_DIRS , DATABASE_NAME , 等. 最重要的设置时ROOT_URLCONF,它将作为URLconf告诉Django在这个站点中那些Python的模块将被用到

还记得什么时候django-admin.py startproject创建文件settings.py和urls.py吗?自动创建的settings.py包含一个ROOT_URLCONF配置用来指向自动产生的urls.py. 打开文件settings.py你将看到如下:

ROOT_URLCONF = 'mysite.urls'

相对应的文件是mysite/urls.py

访问 URL /hello/ 时,Django 根据 ROOT_URLCONF 的设置装载 URLconf 。 然后按顺序逐个匹配URLconf里的URLpatterns,直到找到一个匹配的。 当找到这个匹配 的URLpatterns就调用相关联的view函数,并把 HttpRequest 对象作为第一个参数。

-------

总结一下:

  1. 进来的请求转入/hello/.

  2. Django通过在ROOT_URLCONF配置来决定根URLconf.

  3. Django在URLconf中的所有URL模式中,查找第一个匹配/hello/的条目。

  4. 如果找到匹配,将调用相应的视图函数

  5. 视图函数返回一个HttpResponse

  6. Django转换HttpResponse为一个适合的HTTP response, 以Web page显示出来

------
from django.conf.urls.defaults import *
from mysite.views import hello, current_datetime

urlpatterns = patterns('',
    ('^hello/$', hello),
    ('^time/$', current_datetime),
)

写好视图并且更新URLconf之后,运行命令python manage.py runserver以启动服务,在浏览器中输入http://127.0.0.1:8000/time/。 你将看到当前的日期和时间。

-------

URL配置和松耦合

Django的URL配置就是一个很好的例子。 在Django的应用程序中,URL的定义和视图函数之间是松 耦合的,换句话说,决定URL返回哪个视图函数和实现这个视图函数是在两个不同的地方。 这使得 开发人员可以修改一块而不会影响另一块。

如果我们想要输出这个函数到 一些 URL, 我们只需要修改URL配置而不用 去改动视图的代码。

------

第三个视图 动态URL

如何设计程序来处理任意数量的时差? 答案是:使用通配符(wildcard URLpatterns)。正如我们之前提到过,一个URL模式就是一个正则表达式。因此,这里可以使用d+来匹配1个以上的数字。

urlpatterns = patterns('',
    # ...
    (r'^time/plus/\d+/$', hours_ahead),
    # ...
)

这里使用# …来表示省略了其它可能存在的URL模式定义。 (见上)

这个URL模式将匹配类似 /time/plus/2/ , /time/plus/25/ ,甚至 /time/plus/100000000000/ 的任何URL。 更进一步,让我们把它限制在最大允许99个小时, 这样我们就只允许一个或两个数字,正则表达式的语法就是 \d{1,2} :

(r'^time/plus/\d{1,2}/$', hours_ahead),

备注

在建造Web应用的时候,尽可能多考虑可能的数据输入是很重要的,然后决定哪些我们可以接受。 在这里我们就设置了99个小时的时间段限制。

另外一个重点,正则表达式字符串的开头字母“r”。 它告诉Python这是个原始字符串不需要处理里面的反斜杠(转义字符)。 在普通Python字符串中,反斜杠用于特殊字符的转义。比如n转义成一个换行符。 当你用r把它标示为一个原始字符串后,Python不再视其中的反斜杠为转义字符。也就是说,“n”是两个字符串:“”和“n”。由于反斜杠在Python代码和正则表达式中有冲突,因此建议你在Python定义正则表达式时都使用原始字符串。 从现在开始,本文所有URL模式都用原始字符串。

------

hours_ahead 和我们以前写的 current_datetime 很象,关键的区别在于: 它多了一个额外参数,时间差。以下是view代码:

from django.http import Http404, HttpResponse
import datetime

def hours_ahead(request, offset):
    try:
        offset = int(offset)
except ValueError:
        raise Http404()
    dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
    html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
    return HttpResponse(html)

让我们逐行分析一下代码:

视图函数, hours_ahead , 有 两个 参数: request 和 offset . (见上)

request 是一个 HttpRequest 对象, 就像在 current_datetime 中一样. 再说一次好了: 每一个视图 总是 以一个 HttpRequest 对象作为 它的第一个参数。 (见上)

offset 是从匹配的URL里提取出来的。 例如:如果请求URL是/time/plus/3/,那么offset将会是3;如果请求URL是/time/plus/21/,那么offset将会是21。请注意:捕获值永远都是字符串(string)类型,而不会是整数(integer)类型,即使这个字符串全由数字构成(如:“21”)。

(从技术上来说,捕获值总是Unicode objects,而不是简单的Python字节串,但目前不需要担心这些差别。)

在这里我们命名变量为 offset ,你也可以任意命名它,只要符合Python 的语法。 变量名是无关紧要的,重要的是它的位置,它是这个函数的第二个 参数 (在 request 的后面)。 你还可以使用关键字来定义它,而不是用 位置。

我们在这个函数中要做的第一件事情就是在 offset 上调用 int() . 这会把这个字符串值转换为整数。

请留意:如果你在一个不能转换成整数类型的值上调用int(),Python将抛出一个ValueError异常。如:int(‘foo’)。在这个例子中,如果我们遇到ValueError异常,我们将转为抛出django.http.Http404异常——正如你想象的那样:最终显示404页面(提示信息:页面不存在)。


第四章 模板

模板是一个文本,用于分离文档的表现形式和内容。 模板定义了占位符以及各种用于规范文档该如何显示的各部分基本逻辑(模板标签)。 模板通常用于产生HTML,但是Django的模板也能产生任何基于文本格式的文档。
让我们从一个简单的例子模板开始。 该模板描述了一个向某个与公司签单人员致谢 HTML 页面。 可将其视为一个格式信函:
<ul>
{% for item in item_list %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

{% if ordered_warranty %}
    <p>Your warranty information will be included in the packaging.</p>
{% else %}
    <p>You didn't order a warranty, so you're on your own when
    the products inevitably stop working.</p>
{% endif %}

两个大括号括起来的文字(例如 {{ person_name }} )称为 变量(variable) 。这意味着将按照给定的名字插入变量的值。 如何指定变量的值呢? 稍后就会说明。

大括号和百分号包围的文本(例如 {% if ordered_warranty %} )是 模板标签(template tag) 。标签(tag)定义比较明确,即: 仅通知模板系统完成某些工作的标签。

这个例子中的模板包含一个for标签( {% for item in item_list %} )和一个if 标签({% if ordered_warranty %} )

for标签类似Python的for语句,可让你循环访问序列里的每一个项目。 if 标签,正如你所料,是用来执行逻辑判断的。 在这里,tag标签检查ordered_warranty值是否为True。如果是,模板系统将显示{% if ordered_warranty %}和{% else %}之间的内容;否则将显示{% else %}和{% endif %}之间的内容。{% else %}是可选的。

最后,这个模板的第二段中有一个关于filter过滤器的例子,它是一种最便捷的转换变量输出格式的方式。 如这个例子中的{{ship_date|date:”F j, Y” }},我们将变量ship_date传递给date过滤器,同时指定参数”F j,Y”。date过滤器根据参数进行格式输出。 过滤器是用管道符(|)来调用的,具体可以参见Unix管道符。

Django 模板含有很多内置的tags和filters,我们将陆续进行学习. 附录F列出了很多的tags和filters的列表,

-------

Python代码中使用Django模板的最基本方式如下:

  1. 可以用原始的模板代码字符串创建一个 Template 对象, Django同样支持用指定模板文件路径的方式来创建 Template 对象;

  2. 调用模板对象的render方法,并且传入一套变量context。它将返回一个基于模板的展现字符串,模板中的变量和标签会被context值替换。

代码如下:

>>> from django import template
>>> t = template.Template('My name is {{ name }}.')
>>> c = template.Context({'name': 'Adrian'})
>>> print t.render(c)
My name is Adrian.
>>> c = template.Context({'name': 'Fred'})
>>> print t.render(c)
My name is Fred.
-------

创建模板对象

创建一个 Template 对象最简单的方法就是直接实例化它。 Template 类就在 django.template 模块中,构造函数接受一个参数,原始模板代码。 让我们深入挖掘一下 Python的解释器看看它是怎么工作的。

转到project目录(在第二章由 django-admin.py startproject 命令创建), 输入命令 python manage.py shell 启动交互界面。

一个特殊的Python提示符

如果你曾经使用过Python,你一定好奇,为什么我们运行python manage.py shell而不是python。这两个命令都会启动交互解释器,但是manage.py shell命令有一个重要的不同: 在启动解释器之前,它告诉Django使用哪个设置文件。 Django框架的大部分子系统,包括模板系统,都依赖于配置文件;如果Django不知道使用哪个配置文件,这些系统将不能工作。

-------

了解一些模板系统的基本知识:

>>> from django.template import Template
>>> t = Template('My name is {{ name }}.')
>>> print t

如果你跟我们一起做,你将会看到下面的内容:

<django.template.Template object at 0xb7d5f24c>

0xb7d5f24c 每次都会不一样,这没什么关系;这只是Python运行时 Template 对象的ID。

----

当你创建一个 Template 对象,模板系统在内部编译这个模板到内部格式,并做优化,做好 渲染的准备。 如果你的模板语法有错误,那么在调用 Template() 时就会抛出 TemplateSyntaxError 异常:

>>> from django.template import Template
>>> t = Template('{% notatag %}')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  ...
django.template.TemplateSyntaxError: Invalid block tag: 'notatag'

这里,块标签(block tag)指向的是`` {% notatag %}``,块标签与模板标签是同义的。

-----
模板渲染
一旦你创建一个 Template 对象,你可以用 context 来传递数据给它。 一个context是一系列变量和它们值的集合。

context在Django里表现为 Context 类,在 django.template 模块里。 她的构造函数带有一个可选的参数: 一个字典映射变量和它们的值。 调用 Template 对象 的 render() 方法并传递context来填充模板:

>>> from django.template import Context, Template
>>> t = Template('My name is {{ name }}.')
>>> c = Context({'name': 'Stephane'})
>>> t.render(c)

u'My name is Stephane.'
我们必须指出的一点是,t.render(c)返回的值是一个Unicode对象,不是普通的Python字符串。 你可以在字符串前加上u来声明。 在框架中,Django会一直使用Unicode对象而不是普通的字符串。
-----

字典和Contexts

Python的字典数据类型就是关键字和它们值的一个映射。 Context 和字典很类似, Context 还提供更多的功能,请看第九章。

-----
 使用Django模板系统的基本规则: 写模板,创建 Template 对象,创建 Context , 调用 render() 方法。
 只进行 一次模板创建然后多次调用render()方法渲染会更为高效:
t = Template('Hello, {{ name }}')
for name in ('John', 'Julie', 'Pat'): 
     print t.render(Context({'name': name})) 
-------------
模板系统能够非常简洁地处理更加复杂的数据结构,例如list、dictionary和自定义的对象。
在 Django 模板中遍历复杂数据结构的关键是句点字符 (.)。
点语法也可以用来引用对象的* 方法*。
句点也可用于访问列表索引,不允许使用负数列表索引。
句点查找规则可概括为: 当模板系统在变量名中遇到点时,按照以下顺序尝试进行查找:
  • 字典类型查找 (比如 foo["bar"] )

  • 属性查找 (比如 foo.bar )

  • 方法调用 (比如 foo.bar() )

  • 列表类型索引查找 (比如 foo[bar] )
 

---------------------

方法调用行为

???
------------------------

如何处理无效变量

 
默认情况下,如果一个变量不存在,模板系统会把它展示为空字符串,不做任何事情来表示失败。
-----------------------

玩一玩上下文(context)对象

可以使用标准的Python字典语法(syntax)向``上下文(Context)`` 对象添加或者删除条目:
>>> from django.template import Context
>>> c = Context({"foo": "bar"})
>>> c['foo']
'bar'
>>> del c['foo']
>>> c['foo']
Traceback (most recent call last):
  ...
KeyError: 'foo'
>>> c['newvariable'] = 'hello'
>>> c['newvariable']
'hello'
----------------------

基本的模板标签和过滤器

if/else

{% if %} 标签检查(evaluate)一个变量,如果这个变量为真(即,变量存在,非空,不是布尔值假),系统会显示在 {% if %} 和 {% endif %} 之间的任何内容
---------------------

在Python和Django模板系统中,以下这些对象相当于布尔值的False

  • 空列表([] )

  • 空元组(() )

  • 空字典({} )

  • 空字符串('' )

  • 零值(0 )

  • 特殊对象None

  • 对象False(很明显)

  • 提示:你也可以在自定义的对象里定义他们的布尔值属性(这个是python的高级用法)。
{% if %} 标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not )
------------------------

for

{% for %} 允许我们在一个序列上迭代。 与Python的 for 语句的情形类似,循环语法是 for X in Y ,Y是要迭代的序列而X是在每一个特定的循环中使用的变量名称。 每一次循环中,模板系统会渲染在 {% for %} 和 {% endfor %} 之间的所有内容。
eg.

给定一个运动员列表 athlete_list 变量

{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}

给标签增加一个 reversed 使得该列表被反向迭代:

{% for athlete in athlete_list reversed %}
...
{% endfor %}

可以嵌套使用 {% for %} 标签

Django不支持退出循环操作。 如果我们想退出循环,可以改变正在迭代的变量,让其仅仅包含需要迭代的项目。 同理,Django也不支持continue语句,我们无法让当前迭代操作跳回到循环头部。 (请参看本章稍后的理念和限制小节,了解下决定这个设计的背后原因)
-----------------
forloop
     在每个`` {% for %}``循环里有一个称为`` forloop`` 的模板变量。这个变量有一些提示循环进度信息的属性。
     forloop.counter 总是一个表示当前循环的执行次数的整数计数器。 这个计数器是从1开始的,所以在第一次循环时 forloop.counter 将会被设置为1。
     forloop.counter0 类似于 forloop.counter ,但是它是从0计数的。
     forloop.revcounter 是表示循环中剩余项的整型变量。 在循环初次执行时 forloop.revcounter 将被设置为序列中项的总数。 最后一次循环执行中,这个变量将被置1。
     forloop.revcounter0 类似于 forloop.revcounter ,但它以0做为结束索引。 在第一次执行循环时,该变量会被置为序列的项的个数减1。
     forloop.first 是一个布尔值,如果该迭代是第一次执行,那么它被置为````
forloop.parentloop 是一个指向当前循环的上一级循环的 forloop 对象的引用(在嵌套循环的情况下)。
forloop 变量仅仅能够在循环中使用。 在模板解析器碰到{% endfor %}标签后,forloop就不可访问了。
---------------------

ifequal/ifnotequal

Django模板系统压根儿就没想过实现一个全功能的编程语言,所以它不允许我们在模板中执行Python的语句(还是那句话,要了解更多请参看理念和限制小节)。 但是比较两个变量的值并且显示一些结果实在是个太常见的需求了,所以Django提供了 {% ifequal %} 标签供我们使用。

{% ifequal %} 标签比较两个值,当他们相等时,显示在 {% ifequal %} 和 {% endifequal %} 之中所有的值。

下面的例子比较两个模板变量 user 和 currentuser :

{% ifequal user currentuser %}
    <h1>Welcome!</h1>
{% endifequal %}
注意:

只有模板变量,字符串,整数和小数可以作为 {% ifequal %} 标签的参数。

其他任何类型,例如Python的字典类型、列表类型、布尔类型,不能用在 {% ifequal %} 中。
---------------
注释:
Django模板语言同样提供代码注释。 注释使用 {# #}
如果要实现多行注释,可以使用`` {% comment %}`` 模板标签
---------------

过滤器

就象本章前面提到的一样,模板过滤器是在变量被显示前修改它的值的一个简单方法。 过滤器使用管道字符|。
过滤管道可以被* 套接* ,既一个过滤器管道的输出又可以作为下一个管道的输入。 
下面的例子实现查找列表的第一个元素并将其转化为大写。
{{ my_list|first|upper }}
有些过滤器有参数。 过滤器的参数跟随冒号之后并且总是以双引号包含。 
例如:
{{ bio|truncatewords:"30" }}
这个将显示变量 bio 的前30个词。

以下几个是最为重要的过滤器的一部分。 附录F包含其余的过滤器。

addslashes : 添加反斜杠到任何反斜杠、单引号或者双引号前面。 这在处理包含JavaScript的文本时是非常有用的。

date : 按指定的格式字符串参数格式化 date 或者 datetime 对象, 范例:

     {{ pub_date|date:"F j, Y" }}
--------------------

理念与局限

Python有成十上百的 开放源码的模板语言实现。
如果你还没有完成一个自己的 模板语言,好好考虑写一个,这是一个非常有趣的锻炼。
     业务逻辑应该和表现逻辑相对分开 。我们将模板系统视为控制表现及表现相关逻辑的工具,仅此而已。 模板系统不应提供超出此基本目标的功能。
     出于这个原因,在 Django 模板中是不可能直接调用 Python 代码的。 所有的编程工作基本上都被局限于模板标签的能力范围。 当然,  有可能写出自定义的模板标签来完成任意工作,但这些“超范围”的 Django 模板标签有意地不允许执行任何 Python 代码。
     语法不应受到 HTML/XML 的束缚 。
-----------------

在视图中使用模板

首先考虑把模板保存在文件系统的某个位置并用 Python 内建的文件操作函数来读取文件内容。 假设文件保存在 /home/djangouser/templates/mytemplate.html 中的话,代码就会像下面这样:

from django.template import Template, Context
from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    # Simple way of using templates from the filesystem.
    # This is BAD because it doesn't account for missing files!
    fp = open('/home/djangouser/templates/mytemplate.html')
    t = Template(fp.read())
    fp.close()
    html = t.render(Context({'current_date': now}))
    return HttpResponse(html)

然而,基于以下几个原因,该方法还算不上简洁:

  • 它没有对文件丢失的情况做出处理。 如果文件 mytemplate.html 不存在或者不可读, open() 函数调用将会引发 IOError 异常。

  • 这里对模板文件的位置进行了硬编码。 如果你在每个视图函数都用该技术,就要不断复制这些模板的位置。 更不用说还要带来大量的输入工作!

  • 它包含了大量令人生厌的重复代码。 与其在每次加载模板时都调用 open() 、 fp.read() 和 fp.close() ,还不如做出更佳选择。

 
为了解决这些问题,我们采用了 模板自加载 跟 模板目录 的技巧.
------------------

模板加载

要使用此模板加载API,首先你必须将模板的保存位置告诉框架。

打开你的settings.py配置文件,找到TEMPLATE_DIRS这项设置吧。 它的默认设置是一个空元组(tuple),加上一些自动生成的注释。

该设置告诉 Django 的模板加载机制在哪里查找模板。 选择一个目录用于存放模板并将其添加到 TEMPLATE_DIRS 中:

TEMPLATE_DIRS = (
    '/home/django/mysite/templates',
)
如果你的 TEMPLATE_DIRS只包含一个目录,别忘了在该目录后加上个逗号。
---------------
(晕菜了)

render_to_response()??????

locals() 技巧???????

get_template()中使用子目录???????????

模板继承?????


第五章 模型(数据库层)
 MySQLdb 类库(可以从 http://www.djangoproject.com/r/python-mysql/ 获得)
mysqldb模块在视图中进行数据库查询的笨方法
from django.shortcuts import render_to_response
import MySQLdb

def book_list(request):
db = MySQLdb.connect(user='me', db='mydb', passwd='secret', host='localhost')
cursor = db.cursor()
cursor.execute('SELECT name FROM books ORDER BY name')
names = [row[0] for row in cursor.fetchall()]
db.close()
return render_to_response('book_list.html', {'names': names})
问题:
我们将数据库连接参数硬行编码于代码之中。 理想情况下,这些参数应当保存在 Django 配置中。
我们不得不重复同样的代码: 创建数据库连接、创建数据库游标、执行某个语句、然后关闭数据库。 理想情况下,我们所需要应该只是指定所需的结果。
它把我们栓死在 MySQL 之上。 如果过段时间,我们要从 MySQL 换到 PostgreSQL,就不得不使用不同的数据库适配器(例如 psycopg 而不是 MySQLdb ),改变连接参数,根据 SQL 语句的类型可能还要修改SQL 。 理想情况下,应对所使用的数据库服务器进行抽象,这样一来只在一处修改即可变换数据库服务器。 (如果你正在建立一个开源的Django应用程序来尽可能让更多人使用的话,这个特性是非常适当的。)
-------------

MTV 开发模式

数据存取逻辑、业务逻辑和表现逻辑组合在一起的概念有时被称为软件架构的 Model-View-Controller (MVC)模式。 在这个模式中, Model 代表数据存取层,View 代表的是系统中选择显示什么和怎么显示的部分,Controller 指的是系统中根据用户输入并视需要访问模型,以决定使用哪个视图的那部分。

Django 里更关注的是模型(Model)、模板(Template)和视图(Views),Django 也被称为 MTV 框架 。在 MTV 开发模式中:

  • M 代表模型(Model),即数据存取层。 该层处理与数据相关的所有事务: 如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。

  • T 代表模板(Template),即表现层。 该层处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。

  • V 代表视图(View),即业务逻辑层。 该层包含存取模型及调取恰当模板的相关逻辑。 你可以把它看作模型与模板之间的桥梁
--------------------
数据库配置也是在Django的配置文件里,缺省 是 settings.py 。 打开这个文件并查找数据库配置:
 
DATABASE_ENGINE = ''
DATABASE_NAME = ''
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''
 
配置纲要如下。DATABASE_ENGINE 告诉Django使用哪个数据库引擎。
如果你在 Django 中使用数据库, DATABASE_ENGINE 必须是 Table 5-1 中所列出的值。
 
表 5-1. 数据库引擎设置
设置数据库所需适配器
`` postgresql`` PostgreSQL psycopg 1.x版, http://www.djangoproject.com/r/python-pgsql/1/
postgresql_psycopg2 PostgreSQL psycopg 2.x版, http://www.djangoproject.com/r/python-pgsql/
mysql MySQL MySQLdb , http://www.djangoproject.com/r/python-mysql/.
sqlite3 SQLite 如果使用Python 2.5+则不需要适配器。 否则就使用 pysqlite , http://www.djangoproject.com/r/python-sqlite/
oracle Oracle cx_Oracle , http://www.djangoproject.com/r/python-oracle/.
 
sqlite3创建数据库的方式:进入cmd,在要创建的目录下执行sqlite3.exe SQ.db
退出后,就可以在name里面填写D:\Django\mysite\SQ.db

配置示例:

DATABASE_ENGINE = 'postgresql_psycopg2'

DATABASE_NAME 将数据库名称告知 Django 。 例如:

DATABASE_NAME = 'mydb'

如果使用 SQLite,请对数据库文件指定完整的文件系统路径。 例如:

DATABASE_NAME = '/home/django/mydata.db'

在这个例子中,我们将SQLite数据库放在/home/django目录下,你可以任意选用最合适你的目录。

DATABASE_USER 告诉 Django 用哪个用户连接数据库。 例如: 如果用SQLite,空白即可。

DATABASE_PASSWORD 告诉Django连接用户的密码。 SQLite 用空密码即可。

DATABASE_HOST 告诉 Django 连接哪一台主机的数据库服务器。 如果数据库与 Django 安装于同一台计算机(即本机),可将此项保留空白。 如果你使用SQLite,此项留空。

此处的 MySQL 是一个特例。 如果使用的是 MySQL 且该项设置值由斜杠( '/' )开头,MySQL 将通过 Unix socket 来连接指定的套接字,例如:

DATABASE_HOST = '/var/run/mysql'

一旦在输入了那些设置并保存之后应当测试一下你的配置。 我们可以在`` mysite`` 项目目录下执行上章所提到的`` python manage.py shell`` 来进行测试。 (我们上一章提到过在,`` manager.py shell`` 命令是以正确Django配置启用Python交互解释器的一种方法。 这个方法在这里是很有必要的,因为Django需要知道加载哪个配置文件来获取数据库连接信息。)

输入下面这些命令来测试你的数据库配置:

>>> from django.db import connection
>>> cursor = connection.cursor()
 
如果没有显示什么错误信息,那么你的数据库配置是正确的。 否则,你就得 查看错误信息来纠正错误。 表 5-2 是一些常见错误。
 
注意:???
在MySQL配置完成后,进行测试,结果出现OperationalError: (2003, "Can't connect to MySQL server on '127.0.0.1' (10061)")
这就是曾经用localhost连接出现的那个问题,但是为什么127也这样?
果断换SQlite,没有报错。
 
表 5-2. 数据库配置错误信息
错误信息解决方法
You haven’t set the DATABASE_ENGINE setting yet. 不要以空字符串配置`` DATABASE_ENGINE`` 的值。 表格 5-1 列出可用的值。
Environment variable DJANGO_SETTINGS_MODULE is undefined. 使用`` python manager.py shell`` 命令启动交互解释器,不要以`` python`` 命令直接启动交互解释器。
Error loading _____ module: No module named _____. 未安装合适的数据库适配器 (例如, psycopg 或 MySQLdb )。Django并不自带适配器,所以你得自己下载安装。
_____ isn’t an available database backend. DATABASE_ENGINE 配置成前面提到的合法的数据库引擎。 也许是拼写错误?
database _____ does not exist 设置`` DATABASE_NAME`` 指向存在的数据库,或者先在数据库客户端中执行合适的`` CREATE DATABASE`` 语句创建数据库。
role _____ does not exist 设置`` DATABASE_USER`` 指向存在的用户,或者先在数据库客户端中执创建用户。
could not connect to server 查看DATABASE_HOST和DATABASE_PORT是否已正确配置,并确认数据库服务器是否已正常运行。
 
---------------------

第一个应用程序

一个app是一套Django功能的集合,通常包括模型和视图,按Python的包结构的方式存在。

如果你只是建造一个简单的Web站点,那么可能你只需要一个app就可以了; 但如果是一个包含许多不相关的模块的复杂的网站,例如电子商务和社区之类的站点,那么你可能需要把这些模块划分成不同的app,以便以后复用。

系统对app有一个约定: 如果你使用了Django的数据库层(模型),你 必须创建一个Django app。 模型必须存放在apps中。 因此,为了开始建造 我们的模型,我们必须创建一个新的app。

在`` mysite`` 项目文件下输入下面的命令来创建`` books`` app:

python manage.py startapp books
这个命令并没有输出什么,它只在 mysite 的目录里创建了一个 books 目录。
-------------

在Python代码里定义模型

记录不详
--------------
unicode对象:
 
--------------
 
简单记录:
创建app:python manage.py startapp books
定义模型:
from django.db import models

class Publisher(models.Model):……
class Author(models.Model):……
class Book(models.Model):……
每个模型相当于单个数据库表,每个属性也是这个表中的一个字段。
模型安装:编辑settings.py 文件,注释掉默认模型和其依赖,加上自定义模型
检查有效性:python manage.py validate
列出对应sql语句:python manage sqlall books
将语句同步到数据库:python manage.py syncdb
对象创建和数据存储
处理字符传输用__unicode__()
选择对象Publisher.objects.all()
数据过滤:Publisher.objects.filter(name ="ddddd")
获取单个对象:get
排序order_by("ddd")
组合排序.filter("ddd").order_by("sdf")
限制返回的数据
Publisher.objects.order_by('name')[0]
Publisher.objects.order_by('name')[0:2]
更新多个对象????
删除对象delete()

第六章 Admin
 
django.contrib可以被看作是可选的Python标准库或普遍模式的实际实现
管理工具django.contrib.admin
1、激活管理界面过程
2、使用管理工具
3、将你的Models加入到Admin管理中
admin的工作过程
设置字段、日期、数字可选,自定义方法

第七章 表单
 
介绍如何用Django对用户通过表单提交的数据进行访问、有效性检查以及其它处理。 与此同时,我们将介绍HttpRequest对象和Form对象。
每个view函数的第一个参数是一个HttpRequest对象,获取当前request的一些信息(比如,你正在加载这个页面的用户是谁,或者用的是什么浏览器)。
属性/方法                                   说明                                                                           举例
request.path                     除域名以外的请求路径,以正斜杠开头                               "/hello/"
request.get_host()           主机名(比如,通常所说的域名)                                      "127.0.0.1:8000"or"www.example.com"
request.get_full_path()      请求路径,可能包含查询字符串                                                   "/hello/?print=true"
request.is_secure()           如果通过HTTPS访问,则此方法返回True, 否则返回False           True或者False
request.META 是一个Python字典,包含了所有本次HTTP请求的Header信息,比如用户IP地址和用户Agent(通常是浏览器的名称和版本号)。
 注意,Header信息的完整列表取决于用户所发送的Header信息和服务器端设置的Header信息。
     HTTP_REFERRER ,进站前链接网页
     HTTP_USER_AGENT,用户浏览器的user-agent字符串,例如:
          "Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17".
     REMOTE_ADDR客户端IP,如:"12.345.67.89"
当一个特定的Header数据不存在时,应该用try/except 语句,或者用Python字典的 get() 方法来处理这些“可能不存在的键”。
----------------
HttpRequest对象还有两个属性包含了用户所提交的信息: request.GET 和request.POST。二者都是类字典对象,可以用来访问GET和POST数据。
 

第九章 模板高级进阶
 
模板是一个用Django模板语言标记过的普通的Python字符串。 模板可以包含模板标签和变量。
区块标签被{%%}包围;变量标签被{{}}包围。
context是一个传递给模板的名称到值的映射(类似Python字典)。模板 渲染 就是是通过从context获取值来替换模板中变量并执行所有的模板标签。

posted on 2015-12-15 15:40  cquptzzq  阅读(349)  评论(0编辑  收藏  举报

导航