ID |
English原文 |
中文翻译 |
最近翻译记录 |
状态 |
操作 |
0#翻译 |
Chapter 4: The Django Template System
-------------------------------------
|
第四章 Django模板系统
-------------------------------------
|
996天前 |
|
翻译 |
1#翻译 |
In the previous chapter, you may have noticed something peculiar in how we returned
the text in our example views. Namely, the HTML was hard-coded directly in our
Python code.
|
在前一章中,你可能已经注意到我们在例子视图中返回文本的方式有点特别。也就是说,HTML被硬性地直接写入 Python 代码之中。
|
924天前 |
|
翻译 |
2#翻译 |
This arrangement leads to several problems:
|
这种处理会导致一些问题:
|
996天前 |
|
翻译 |
3#翻译 |
* Any change to the design of the page requires a change to the Python code. The
design of a site tends to change far more frequently than the underlying Python
code, so it would be convenient if the the design could change without needing
to modify the Python code.
|
* 对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。 |
996天前 |
|
翻译 |
4#翻译 |
* Writing Python code and designing HTML are two different disciplines, and most
professional Web development environments split these responsibilities between
separate people (or even separate departments). Designers and HTML/CSS coders
shouldnt have to edit Python code to get their job done; they should deal with
HTML.
|
* Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。设计人员和 HTML/CSS 编写人员都不应该通过编辑 Python 代码来完成自己的工作;他们应该处理的是 HTML。 |
996天前 |
|
翻译 |
5#翻译 |
* Similarly, its most efficient if programmers can work on Python code and
designers can work on templates at the same time, rather than one person waiting
for the other to finish editing a single file that contains both Python and
HTML.
|
* 同理,程序员编写 Python 代码和设计人员制作模板同时进行的工作方式效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python 又包含 HTML 的文件的编辑工作。 |
996天前 |
|
翻译 |
6#翻译 |
For these reasons, its much cleaner and more maintainable to separate the design of
the page from the Python code itself. We can do this with Djangos *template system*
, which we discuss in this chapter.
|
基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。我们可以使用
Django的 *模板系统* (Template System)来实现这种模式,这就是本章要具体讨论的问题。
|
996天前 |
|
翻译 |
7#翻译 |
Template System Basics
``````````````````````
|
模板系统基本知识
``````````````````````
|
996天前 |
|
翻译 |
8#翻译 |
A Django template is a string of text that is intended to separate the presentation
of a document from its data. A template defines placeholders and various bits of
basic logic (i.e., template tags) that regulate how the document should be
displayed. Usually, templates are used for producing HTML, but Django templates are
equally capable of generating any text-based format.
|
模板系统基本知识
``````````````````````
|
996天前 |
|
翻译 |
9#翻译 |
Lets dive in with a simple example template. This template describes an HTML page
that thanks a person for placing an order with a company. Think of it as a form
letter:
|
让我们深入分析一个简单的例子模板。该模板描述了一个向某个与公司签单人员致谢 HTML 页面。可将其视为一个格式信函: |
996天前 |
|
翻译 |
12#翻译 |
This template is basic HTML with some variables and template tags thrown in. Lets
step through it:
|
该模板是一段添加了些许变量和模板标签的基础 HTML 。让我们逐句过一遍: |
996天前 |
|
翻译 |
13#翻译 |
Any text surrounded by a pair of braces (e.g., ``{{ person_name }}`` ) is a
*variable* . This means insert the value of the variable with the given name.
How do we specify the values of the variables? Well get to that in a moment.
|
用两个大括号括起来的文字(例如 ``{{ person_name }}`` )是 *变量(variable)* 。这意味着将按照给定的名字插入变量的值。如何指定变量的值呢?稍后就会说明。
|
996天前 |
|
翻译 |
14#翻译 |
Any text thats surrounded by curly braces and percent signs (e.g., ``{% if
ordered_warranty %}`` ) is a *template tag* . The definition of a tag is quite
broad: a tag just tells the template system to do something.
|
被大括号和百分号包围的文本(例如 ``{% if ordered_warranty %}`` )是 *模板标签(template tag)* 。标签(tag)定义比较明确,即:仅通知模板系统完成某些工作的标签。 |
996天前 |
|
翻译 |
15#翻译 |
This example template contains two tags: the ``{% for item in item_list %}`` tag
(a ``for`` tag) and the ``{% if ordered_warranty %}`` tag (an ``if`` tag).
|
这个示例模板包含两个标签(tag): ``{% for item in item_list %}`` 标签(一个 ``for`` 标签)
和 ``{% if ordered_warranty %}`` 标签 (一个 ``if`` 标签)。
|
996天前 |
|
翻译 |
16#翻译 |
A ``for`` tag acts as a simple loop construct, letting you loop over each item
in a sequence. An ``if`` tag, as you may expect, acts as a logical if statement.
In this particular case, the tag checks whether the value of the
``ordered_warranty`` variable evaluates to ``True`` . If it does, the template
system will display everything between the ``{% if ordered_warranty %}`` and
``{% endif %}`` . If not, the template system wont display it. The template
system also supports ``{% else %}`` and other various logic statements.
|
``for`` 标签用于构建简单的循环,允许你遍历循环中的每一项。 ``if`` 标签,正如你所料,是用来执行逻辑判断的。在这个例子中标签检测 ``ordered_warranty`` 变量值是否为 ``True`` 。
如果是,模板系统将显示 ``{% if ordered_warranty %}`` 与 ``{% endif %}`` 之间的所有内容。
如果不是模板系统不会显示它。它当然也支持 ``{% else %}`` 以及其他多种逻辑判断方式。
|
996天前 |
|
翻译 |
17#翻译 |
Finally, the second paragraph of this template has an example of a *filter* ,
with which you can alter the display of a variable. In this example, ``{{
ship_date|date:"F j, Y" }}`` , were passing the ``ship_date`` variable to the
``date`` filter, giving the ``date`` filter the argument ``"F j, Y"`` . The
``date`` filter formats dates in a given format, as specified by that argument.
Filters are attached using a pipe character (``|`` ), as a reference to Unix
pipes.
|
最后,这个模板的第二段落有一个 *filter* 过滤器的例子,它能让你用来转换变量的输出,
在这个例子中, ``{{ship_date|date:"F j, Y" }}`` 将变量 ``ship_date`` 用 ``date``
过滤器来转换,转换的参数是 ``"F j, Y"`` . ``date`` 过滤器根据指定的参数进行格式输
出.过滤器是用管道字符( ``|`` )来调用的,就和Unix管道一样. |
996天前 |
|
翻译 |
18#翻译 |
Each Django template has access to several built-in tags and filters, many of which
are discussed in the sections that follow. Appendix F contains the full list of tags
and filters, and its a good idea to familiarize yourself with that list so you know
whats possible. Its also possible to create your own filters and tags, which we
cover in Chapter 10.
|
Django 模板含有很多内置的tags和filters,我们将陆续进行学习.
附录F列出了很多的tags和filters的列表,熟悉这些列表对你来说是个好建议.
学习完第十章,你就明白怎么去创建自己的filters和tags了. |
996天前 |
|
翻译 |
19#翻译 |
Using the Template System
`````````````````````````
|
如何使用模板系统
`````````````````````````
|
996天前 |
|
翻译 |
20#翻译 |
To use the template system in Python code, just follow these two steps:
|
想要在Python代码中使用模板系统,只需遵循下面两个步骤:
|
996天前 |
|
翻译 |
21#翻译 |
1. Create a ``Template`` object by providing the raw template code as a string.
Django also offers a way to create ``Template`` objects by designating the path
to a template file on the filesystem; well examine that in a bit.
|
1. 可以用原始的模板代码字符串创建一个 ``Template`` 对象,
Django同样支持用指定模板文件路径的方式来创建 ``Template`` 对象; |
996天前 |
|
翻译 |
22#翻译 |
2. Call the ``render()`` method of the ``Template`` object with a given set of
variables (i.e., the context). This returns a fully rendered template as a
string, with all of the variables and block tags evaluated according to the
context.
|
2. 调用 ``Template`` 对象的 ``render()`` 方法并提供给他变量(i.e., 内容).
它将返回一个完整的模板字符串内容,包含了所有标签块与变量解析后的内容.
|
996天前 |
|
翻译 |
23#翻译 |
The following sections describe each step in more detail.
|
以下部分逐步的详细介绍 |
996天前 |
|
翻译 |
24#翻译 |
Creating Template Objects
'''''''''''''''''''''''''
|
创建模板对象
'''''''''''' |
996天前 |
|
翻译 |
25#翻译 |
The easiest way to create a ``Template`` object is to instantiate it directly. The
``Template`` class lives in the ``django.template`` module, and the constructor
takes one argument, the raw template code. Lets dip into the Python interactive
interpreter to see how this works in code.
|
创建一个 ``Template`` 对象最简单的方法就是直接实例化它。 ``Template`` 类就在
``django.template`` 模块中,构造函数接受一个参数,原始模板代码。让我们深入挖掘一下
Python的解释器看看它是怎么工作的。
|
996天前 |
|
翻译 |
26#翻译 |
Interactive Interpreter Examples
|
交互式示例 |
996天前 |
|
翻译 |
27#翻译 |
Throughout this book, we feature example Python interactive interpreter sessions.
You can recognize these examples by the triple greater-than signs (``>>>`` ), which
designate the interpreters prompt. If youre copying examples from this book, dont
copy those greater-than signs.
|
在本书中,我们喜欢用和Python解释器的交互来举例。
你可以通过三个> ( ``>>>`` ) 识别它们,它们相当于Python解释器的提示符。
如果你要拷贝例子,请不要拷贝这3个>字符。 |
996天前 |
|
翻译 |
28#翻译 |
Multiline statements in the interactive interpreter are padded with three dots
(``...`` ), for example:
|
多行语句则在前面加了3个小数点(``...`` ),例如: |
996天前 |
|
翻译 |
31#翻译 |
Those three dots at the start of the additional lines are inserted by the Python
shelltheyre not part of our input. We include them here to be faithful to the actual
output of the interpreter. If you copy our examples to follow along, dont copy those
dots.
|
这3个点是Python解释器自动加入的,不需要你的输入。我们包含它们是为了忠实呈现解释器的
真实输出。同样道理,拷贝时不要拷贝这3个小数点符号。 |
996天前 |
|
翻译 |
32#翻译 |
From within the project directory created by ``django-admin.py startproject`` (as
covered in Chapter 2), type ``python manage.py shell`` to start the interactive
interpreter. Heres a basic walk-through:
|
转到project目录(在第二章由 ``django-admin.py startproject`` 命令创建),
输入命令 ``python manage.py shell`` 启动交互界面。下面是一些基本操作: |
971天前 |
|
翻译 |
35#翻译 |
If youre following along interactively, youll see something like this:
|
如果你跟我们一起做,你将会看到下面的内容: |
1475天前 |
|
翻译 |
38#翻译 |
That ``0xb7d5f24c`` will be different every time, and it doesnt really matter; its
simply the Python identity of the ``Template`` object.
|
``0xb7d5f24c`` 每次都会不一样,这没什么关系;这只是Python运行时 ``Template`` 对象的ID。 |
1327天前 |
|
翻译 |
39#翻译 |
Django Settings
|
Django 设置 |
1475天前 |
|
翻译 |
40#翻译 |
When using Django, you need to tell Django which settings to use. Interactively,
this is typically done using ``python manage.py shell`` , but youve got a few other
options described in Appendix E.
|
当你使用Django时,你需要告诉Django使用哪个配置。在交互模式下,通常运行命令
``python manage.py shell`` 来做这个,附录E里还有一些其他的一些选项。 |
1327天前 |
|
翻译 |
41#翻译 |
When you create a ``Template`` object, the template system compiles the raw template
code into an internal, optimized form, ready for rendering. But if your template
code includes any syntax errors, the call to ``Template()`` will cause a
``TemplateSyntaxError`` exception:
|
当你创建一个 ``Template`` 对象,模板系统在内部编译这个模板到内部格式,并做优化,做好
渲染的准备。如果你的模板语法有错误,那么在调用 ``Template()`` 时就会抛出
``TemplateSyntaxError`` 异常: |
1475天前 |
|
翻译 |
44#翻译 |
The system raises a ``TemplateSyntaxError`` exception for any of the following
cases:
|
系统会在下面的情形抛出 ``TemplateSyntaxError`` 异常: |
1372天前 |
|
翻译 |
45#翻译 |
* Invalid block tags
|
* 无效的块标签 |
1475天前 |
|
翻译 |
46#翻译 |
* Invalid arguments to valid block tags
|
* 无效的参数 |
1475天前 |
|
翻译 |
47#翻译 |
* Invalid filters
|
* 无效的过滤器 |
1475天前 |
|
翻译 |
48#翻译 |
* Invalid arguments to valid filters
|
* 过滤器的参数无效 |
1475天前 |
|
翻译 |
49#翻译 |
* Invalid template syntax
|
* 无效的模板语法 |
1475天前 |
|
翻译 |
50#翻译 |
* Unclosed block tags (for block tags that require closing tags)
|
* 未封闭的块标签 (针对需要封闭的块标签) |
1475天前 |
|
翻译 |
51#翻译 |
Rendering a Template
''''''''''''''''''''
|
模板渲染
''''''''''''''''''''
|
1481天前 |
|
翻译 |
52#翻译 |
Once you have a ``Template`` object, you can pass it data by giving it a *context* .
A context is simply a set of variables and their associated values. A template uses
this to populate its variable tags and evaluate its block tags.
|
一旦你创建一个 ``Template`` 对象,你可以用 *context* 来传递数据给它。
一个context是一系列变量和它们值的集合。模板使用它来赋值模板变量标签和
执行块标签。 |
1394天前 |
|
翻译 |
53#翻译 |
A context is represented in Django by the ``Context`` class, which lives in the
``django.template`` module. Its constructor takes one optional argument: a
dictionary mapping variable names to variable values. Call the ``Template`` objects
``render()`` method with the context to fill the template:
|
context在Django里表现为 ``Context`` 类,在 ``django.template`` 模块里。
它构造是有一个可选参数:一个字典映射变量和它们的值。调用 ``Template`` 对象
的 ``render()`` 方法并传递context来填充模板: |
1475天前 |
|
翻译 |
56#翻译 |
Dictionaries and Contexts
|
字典和Contexts |
1475天前 |
|
翻译 |
57#翻译 |
A Python dictionary is a mapping between known keys and variable values. A
``Context`` is similar to a dictionary, but a ``Context`` provides additional
functionality, as covered in Chapter 10.
|
Python的字典数据类型就是关键字和它们值的一个映射。 ``Context`` 和字典很类似,
``Context`` 还提供更多的功能,请看第十章。 |
1167天前 |
|
翻译 |
58#翻译 |
Variable names must begin with a letter (A-Z or a-z) and may contain digits,
underscores, and dots. (Dots are a special case well get to in a moment.) Variable
names are case sensitive.
|
变量名必须由英文字符开始 (A-Z或a-z)并可以包含数字字符、下划线和小数点。
(小数点在这里有特别的用途,稍后我们会讲到)变量是大小写敏感的。 |
1475天前 |
|
翻译 |
59#翻译 |
Heres an example of template compilation and rendering, using the sample template
from the beginning of this chapter:
|
下面是编写模板并渲染的示例: |
1475天前 |
|
翻译 |
62#翻译 |
Lets step through this code one statement at a time:
|
让我们逐句看看这段代码: |
1256天前 |
|
翻译 |
63#翻译 |
First, we import the classes ``Template`` and ``Context`` , which both live in
the module ``django.template`` .
|
首先我们导入 (import)类 ``Template`` 和 ``Context`` ,它们都在模块
``django.template`` 里。 |
1271天前 |
|
翻译 |
64#翻译 |
We save the raw text of our template into the variable ``raw_template`` . Note
that we use triple quote marks to designate the string, because it wraps over
multiple lines; in Python codde, strings designated with single quote marks
cannot be wrapped over multiple lines.
|
我们把模板原始文本保存到变量 ``raw_template`` 。注意到我们使用了三个引号来
标识这些文本,因为这样可以包含多行。这是Python的一个语法。 |
1475天前 |
|
翻译 |
65#翻译 |
Next, we create a template object, ``t`` , by passing ``raw_template`` to the
``Template`` class constructor.
|
接下来,我们创建了一个模板对象 ``t`` ,把 ``raw_template`` 作为 ``Template`` 类
的构造的参数。 |
1256天前 |
|
翻译 |
66#翻译 |
We import the ``datetime`` module from Pythons standard library, because well
need it in the following statement.
|
我们从Python的标准库导入 ``datetime`` 模块,以后我们将会使用它。 |
1475天前 |
|
翻译 |
67#翻译 |
Then, we create a ``Context`` object, ``c`` . The ``Context`` constructor takes
a Python dictionary, which maps variable names to values. Here, for example, we
specify that the ``person_name`` is ``'John Smith'`` , ``product`` is ``'Super
Lawn Mower'`` , and so forth.
|
然后,我们创建一个 ``Context`` 对象, ``c`` 。 ``Context`` 构造的参数是Python
字典数据类型,在这里,我们给的参数是 ``person_name`` 值为 ``'John Smith'`` ,
``product`` 值为 ``'Super Lawn Mower'`` ,等等。 |
1475天前 |
|
翻译 |
68#翻译 |
Finally, we call the ``render()`` method on our template object, passing it the
context. This returns the rendered templatethat is, it replaces template
variables with the actual values of the variables, and it executes any block
tags.
|
最后,我们在模板对象上调用 ``render()`` 方法,传递 context参数给它。
这是返回渲染后的模板的方法,它会替换模板变量为真实的值和执行块标签。 |
1426天前 |
|
翻译 |
69#翻译 |
Note that the warranty paragraph was displayed because the ``ordered_warranty``
variable evaluated to ``True`` . Also note the date, ``April 2, 2009`` , which
is displayed according to the format string ``'F j, Y'`` . (We explain format
strings for the ``date`` filter shortly.)
|
注意,warranty paragraph显示是因为 ``ordered_warranty`` 的值为 ``True`` .
注意时间的显示, ``April 2, 2009`` , 它是按 ``'F j, Y'`` 格式显示的。
(我们很快就会在 ``date`` 过滤器解释这些格式) |
1475天前 |
|
翻译 |
70#翻译 |
If youre new to Python, you may wonder why this output includes newline
characters (``'\n'`` ) rather than displaying the line breaks. Thats happening
because of a subtlety in the Python interactive interpreter: the call to
``t.render(c)`` returns a string, and by default the interactive interpreter
displays the *representation* of the string, rather than the printed value of
the string. If you want to see the string with line breaks displayed as true
line breaks rather than ``'\n'`` characters, use the ``print`` statement:
``print t.render(c)`` .
|
如果你是Python初学者,你可能在想为什么输出里有回车换行的字符(``'\n'`` )而不是
显示回车换行?因为这是Python交互解释器的缘故:调用 ``t.render(c)`` 返回字符串,
解释器缺省显示这些字符串的 *真实内容呈现* ,而不是打印这个变量的值。
要显示换行而不是 ``'\n'`` ,使用 ``print`` 语句: ``print t.render(c)`` 。 |
1475天前 |
|
翻译 |
71#翻译 |
Those are the fundamentals of using the Django template system: just write a
template, create a ``Template`` object, create a ``Context`` , and call the
``render()`` method.
|
这就是使用Django模板系统的基本规则:写模板,创建 ``Template`` 对象,创建 ``Context`` ,
调用 ``render()`` 方法。 |
1475天前 |
|
翻译 |
72#翻译 |
Multiple Contexts, Same Template
''''''''''''''''''''''''''''''''
|
同一模板,多个上下文
''''''''''''''''''''''''''''''''
|
1254天前 |
|
翻译 |
73#翻译 |
Once you have a ``Template`` object, you can render multiple contexts through it,
for example:
|
一旦有了 ``模板`` 对象,你就可以通过它渲染多个背景(context),例如:
|
1257天前 |
|
翻译 |
76#翻译 |
Whenever youre using the same template source to render multiple contexts like this,
its more efficient to create the ``Template`` object *once* , and then call
``render()`` on it multiple times:
|
无论何时像这样使用同一模板源渲染多个背景,只创建 *一次* ``模板`` 对象,然后对它多次调用 ``render()`` 将会更加高效。
|
1257天前 |
|
翻译 |
79#翻译 |
Djangos template parsing is quite fast. Behind the scenes, most of the parsing
happens via a single call to a short regular expression. This is in stark contrast
to XML-based template engines, which incur the overhead of an XML parser and tend to
be orders of magnitude slower than Djangos template rendering engine.
|
Django 模板解析非常快捷。大部分的解析工作都是在后台通过对简短正则表达式一次性调用来完成。这和基于 XML 的模板引擎形成鲜明对比,那些引擎承担了 XML 解析器的开销,且往往比 Django 模板渲染引擎要慢上几个数量级。
|
1257天前 |
|
翻译 |
80#翻译 |
Context Variable Lookup
'''''''''''''''''''''''
|
背景变量的查找
'''''''''''''''''''''''
|
1257天前 |
|
翻译 |
81#翻译 |
In the examples so far, weve passed simple values in the contextsmostly strings,
plus a ``datetime.date`` example. However, the template system elegantly handles
more complex data structures, such as lists, dictionaries, and custom objects.
|
在到目前为止的例子中,我们通过 context 传递的简单参数值主要是字符串,还有一个 ``datetime.date`` 范例。然而,模板系统能够非常简洁地处理更加复杂的数据结构,例如list、dictionary和自定义的对象。
|
1257天前 |
|
翻译 |
82#翻译 |
The key to traversing complex data structures in Django templates is the dot
character (``.`` ). Use a dot to access dictionary keys, attributes, indices, or
methods of an object.
|
在 Django 模板中遍历复杂数据结构的关键是句点字符 (``.``)。使用句点可以访问字典的键值、属性、索引和对象的方法。
|
1257天前 |
|
翻译 |
83#翻译 |
This is best illustrated with a few examples. For instance, suppose youre passing a
Python dictionary to a template. To access the values of that dictionary by
dictionary key, use a dot:
|
最好是用几个例子来说明一下。比如,假设你要向模板传递一个 Python 字典。要通过字典键访问该字典的值,可使用一个句点: |
1257天前 |
|
翻译 |
86#翻译 |
Similarly, dots also allow access of object attributes. For example, a Python
``datetime.date`` object has ``year`` , ``month`` , and ``day`` attributes, and you
can use a dot to access those attributes in a Django template:
|
同样,也可以通过句点来访问对象的属性。比方说, Python 的 ``datetime.date`` 对象有 ``year`` 、 ``month`` 和 ``day`` 几个属性,你同样可以在模板中使用句点来访问这些属性: |
1233天前 |
|
翻译 |
89#翻译 |
This example uses a custom class:
|
下例使用了一个自定义类: |
1257天前 |
|
翻译 |
92#翻译 |
Dots are also used to call methods on objects. For example, each Python string has
the methods ``upper()`` and ``isdigit()`` , and you can call those in Django
templates using the same dot syntax:
|
句点还用于调用对象的方法。例如,每个 Python 字符串都有 ``upper()`` 和 ``isdigit()`` 方法,你在模板中可以使用同样的句点语法来调用它们: |
1257天前 |
|
翻译 |
95#翻译 |
Note that you dont include parentheses in the method calls. Also, its not possible
to pass arguments to the methods; you can only call methods that have no required
arguments. (We explain this philosophy later in this chapter.)
|
注意你不能在方法调用中使用圆括号。而且也无法给该方法传递参数;你只能调用不需参数的方法。(我们将在本章稍后部分解释该设计观。) |
1257天前 |
|
翻译 |
96#翻译 |
Finally, dots are also used to access list indices, for example:
|
最后,句点也可用于访问列表索引,例如: |
1257天前 |
|
翻译 |
99#翻译 |
Negative list indices are not allowed. For example, the template variable ``{{
items.-1 }}`` would cause a ``TemplateSyntaxError`` .
|
不允许使用负数列表索引。像 ``{{ items.-1 }}`` 这样的模板变量将会引发
``TemplateSyntaxError`` 异常。 |
1257天前 |
|
翻译 |
100#翻译 |
Python Lists
|
Python 列表类型 |
1474天前 |
|
翻译 |
101#翻译 |
Python lists have 0-based indices so that the first item is at index 0, the second
is at index 1, and so on.
|
Python列表类型的索引是从0开始的,第一个元素的索引是0,第二个是1,以此类推。 |
1474天前 |
|
翻译 |
102#翻译 |
The dot lookups can be summarized like this: when the template system encounters a
dot in a variable name, it tries the following lookups, in this order:
|
句点查找规则可概括为:当模板系统在变量名中遇到点时,按照以下顺序尝试进行查找: |
1257天前 |
|
翻译 |
103#翻译 |
* Dictionary lookup (e.e., ``foo["bar"]`` )
|
* 字典查找 (比如 ``foo["bar"]`` ) |
319天前 |
|
翻译 |
104#翻译 |
* Attribute lookup (e.g., ``foo.bar`` )
|
* 属性查找 (比如 ``foo.bar`` ) |
1323天前 |
|
翻译 |
105#翻译 |
* Method call (e.g., ``foo.bar()`` )
|
* 方法调用 (比如 ``foo.bar()`` )
|
1474天前 |
|
翻译 |
106#翻译 |
* List-index lookup (e.g., ``foo[bar]`` )
|
* 列表类型索引查找 (比如 ``foo[bar]`` ) |
1435天前 |
|
翻译 |
107#翻译 |
The system uses the first lookup type that works. Its short-circuit logic.
|
系统使用所找到的第一个有效类型。这是一种短路逻辑。 |
1257天前 |
|
翻译 |
108#翻译 |
Dot lookups can be nested multiple levels deep. For instance, the following example
uses ``{{ person.name.upper }}`` , which translates into a dictionary lookup
(``person['name']`` ) and then a method call (``upper()`` ):
|
句点查找可以多级深度嵌套。例如在下面这个例子中 ``{{person.name.upper}}`` 会转换成字典类型查找( ``person['name']`` ) 然后是方法调用( ``upper()`` ): |
1257天前 |
|
翻译 |
111#翻译 |
Method Call Behavior
....................
|
方法调用行为
....................
|
1257天前 |
|
翻译 |
112#翻译 |
Method calls are slightly more complex than the other lookup types. Here are some
things to keep in mind:
|
方法调用比其他类型的查找略为复杂一点。以下是一些注意事项: |
1257天前 |
|
翻译 |
113#翻译 |
If, during the method lookup, a method raises an exception, the exception will
be propagated, unless the exception has an attribute ``silent_variable_failure``
whose value is ``True`` . If the exception *does* have a
``silent_variable_failure`` attribute, the variable will render as an empty
string, for example:
|
在方法查找过程中,如果某方法抛出一个异常,除非该异常有一个 ``silent_variable_failure`` 属性并且值为 ``True`` ,否则的话它将被传播。如果该异常 *确有* 属性 ``silent_variable_failure`` ,那么(所查找)变量将被渲染为空字符串,例如: |
1257天前 |
|
翻译 |
116#翻译 |
A method call will only work if the method has no required arguments. Otherwise,
the system will move to the next lookup type (list-index lookup).
|
仅在方法无需传入参数时,其调用才有效。否则,系统将会转移到下一个查找类型(列表索引查找)。 |
1257天前 |
|
翻译 |
117#翻译 |
Obviously, some methods have side effects, and it would be foolish at best, and
possibly even a security hole, to allow the template system to access them.
|
显然,有些方法是有副作用的,好的情况下允许模板系统访问它们可能只是干件蠢事,坏的情况下甚至会引发安全漏洞。 |
1257天前 |
|
翻译 |
118#翻译 |
Say, for instance, you have a ``BankAccount`` object that has a ``delete()``
method. A template shouldnt be allowed to include something like ``{{
account.delete }}`` .
|
例如,你的一个 ``BankAccount`` 对象有一个 ``delete()`` 方法。不应该允许模板包含像 ``{{account.delete}}`` 这样的方法调用。 |
1257天前 |
|
翻译 |
119#翻译 |
To prevent this, set the function attribute ``alters_data`` on the method:
|
要防止这样的事情发生,必须设置该方法的 ``alters_data`` 函数属性: |
1257天前 |
|
翻译 |
122#翻译 |
The template system wont execute any method marked in this way. In other words,
if a template includes ``{{ account.delete }}`` , that tag will not execute the
``delete()`` method. It will fail silently.
|
模板系统不会执行任何以该方式进行标记的方法。也就是说,如果模板包含了 ``{{account.delete}}`` ,该标签不会调用 ``delete()`` 方法。它只会安静地失败(并不会引发异常)。 |
1257天前 |
|
翻译 |
123#翻译 |
How Invalid Variables Are Handled
.................................
|
如何处理无效变量
.................... |
1257天前 |
|
翻译 |
124#翻译 |
By default, if a variable doesnt exist, the template system renders it as an empty
string, failing silently, for example:
|
默认情况下,如果一个变量不存在,模板系统会把它展示为空字符串,不做任何事情地表示失败,例如: |
1473天前 |
|
翻译 |
127#翻译 |
The system fails silently rather than raising an exception because its intended to
be resilient to human error. In this case, all of the lookups failed because
variable names have the wrong case or name. In the real world, its unacceptable for
a Web site to become inaccessible due to a small template syntax error.
|
系统静悄悄地表示失败,而不是引发一个异常,因为这通常是人为错误造成的。这种情况下,因为变量名有错误的状况或名称,
所有的查询都会失败。现实世界中,对于一个web站点来说,如果仅仅因为一个小的模板语法错误而造成无法访问,这是不可接受的。 |
1297天前 |
|
翻译 |
128#翻译 |
Note that its possible to change Djangos default behavior in this regard, by
tweaking a setting in your Django configuration. We discuss this further in Chapter
10.
|
注意,我们是可以有机会通过更改Django的配置以在这点上改变Django的默认行为的。
我们会在第10章进行进一步的讨论的。 |
1473天前 |
|
翻译 |
129#翻译 |
Playing with Context Objects
''''''''''''''''''''''''''''
|
玩一玩上下文(context)对象
''''''''''''''''''''''''''''
|
1473天前 |
|
翻译 |
130#翻译 |
Most of the time, youll instantiate ``Context`` objects by passing in a fully
populated dictionary to ``Context()`` . But you can add and delete items from a
``Context`` object once its been instantiated, too, using standard Python dictionary
syntax:
|
多数时间,你可以通过传递一个完全填充(full populated)的字典给 ``Context()`` 来初始化 ``上下文(Context)`` 。
但是初始化以后,你也可以从``上下文(Context)`` 对象添加或者删除条目,使用标准的Python字典语法(syntax): |
1297天前 |
|
翻译 |
133#翻译 |
Basic Template Tags and Filters
```````````````````````````````
|
基本的模板标签和过滤器
`````````````````````` |
1473天前 |
|
翻译 |
134#翻译 |
As weve mentioned already, the template system ships with built-in tags and filters.
The sections that follow provide a rundown of the most common tags and filters.
|
像我们以前提到过的,模板系统带有内置的标签和过滤器。
下面的章节提供了一个多数通用标签和过滤器的简要说明。 |
1473天前 |
|
翻译 |
135#翻译 |
Tags
''''
|
标签
'''''' |
1473天前 |
|
翻译 |
136#翻译 |
if/else
.......
|
if/else
.......
|
1473天前 |
|
翻译 |
137#翻译 |
The ``{% if %}`` tag evaluates a variable, and if that variable is true (i.e., it
exists, is not empty, and is not a false Boolean value), the system will display
everything between ``{% if %}`` and ``{% endif %}`` , for example:
|
``{% if %}`` 标签检查(evaluate)一个变量,如果这个变量为真(即,变量存在,非空,不是布尔值假),系统会显示在 ``{% if %}`` 和 ``{% endif %}`` 之间的任何内容,例如: |
1473天前 |
|
翻译 |
140#翻译 |
An ``{% else %}`` tag is optional:
|
``{% else %}`` 标签是可选的: |
1473天前 |
|
翻译 |
143#翻译 |
Python Truthiness
|
Python 的“真值”
|
1346天前 |
|
翻译 |
144#翻译 |
In Python, the empty list (``[]`` ), tuple (``()`` ), dictionary (``{}`` ), string
(``''`` ), zero (``0`` ), and the special object ``None`` are ``False`` in a Boolean
context. Everything else is ``True`` .
|
在python中空的列表 ( ``[]`` ),tuple( ``()`` ),字典( ``{}`` ),字符串( ``''`` ),零( ``0`` ),还有 ``None`` 对象,在逻辑判断中都为假,其他的情况都为真。
|
1461天前 |
|
翻译 |
145#翻译 |
The ``{% if %}`` tag accepts ``and`` , ``or`` , or ``not`` for testing multiple
variables, or to negate a given variable. For example:
|
``{% if %}`` 标签接受 ``and`` , ``or`` 或者 ``not`` 关键字来对多个变量做判断
,或者对变量取反( ``not`` ),例如:
|
1461天前 |
|
翻译 |
148#翻译 |
``{% if %}`` tags dont allow ``and`` and ``or`` clauses within the same tag, because
the order of logic would be ambiguous. For example, this is invalid:
|
``{% if %}`` 标签不允许在同一个标签中同时使用 ``and`` 和 ``or`` ,因为逻辑上可能模糊的,例如,如下示例是错误的:
|
1459天前 |
|
翻译 |
151#翻译 |
The use of parentheses for controlling order of operations is not supported. If you
find yourself needing parentheses, consider performing logic in the view code in
order to simplify the templates. Even so, if you need to combine ``and`` and ``or``
to do advanced logic, just use nested ``{% if %}`` tags, for example:
|
系统不支持用圆括号来组合比较操作。如果你发现需要组合操作,你可以考虑用逻辑语句来简化
模板的处理。例如,你需要组合 ``and`` 和 ``or`` 做些复杂逻辑判断,可以使用嵌套的
``{% if %}`` 标签,示例如下: |
1471天前 |
translating.... |
翻译 |
154#翻译 |
Multiple uses of the same logical operator are fine, but you cant combine different
operators. For example, this is valid:
|
多次使用同一个逻辑操作符是没有问题的,但是我们不能把不同的操作符组合起来。比如这样的代码是没问题的: |
1464天前 |
|
翻译 |
157#翻译 |
There is no ``{% elif %}`` tag. Use nested ``{% if %}`` tags to accomplish the same
thing:
|
并没有 ``{% elif %}`` 标签,请使用嵌套的 ``{% if %}`` 标签来达成同样的效果: |
1303天前 |
|
翻译 |
160#翻译 |
Make sure to close each ``{% if %}`` with an ``{% endif %}`` . Otherwise, Django
will throw a ``TemplateSyntaxError`` .
|
一定要用 ``{% endif %}`` 关闭每一个 ``{% if %}`` 标签。否则Django会抛出 ``TemplateSyntaxError`` 。 |
1461天前 |
|
翻译 |
161#翻译 |
for
...
|
for
... |
1436天前 |
|
翻译 |
162#翻译 |
The ``{% for %}`` tag allows you to loop over each item in a sequence. As in Pythons
``for`` statement, the syntax is ``for X in Y`` , where ``Y`` is the sequence to
loop over and ``X`` is the name of the variable to use for a particular cycle of the
loop. Each time through the loop, the template system will render everything between
``{% for %}`` and ``{% endfor %}`` .
|
``{% for %}`` 允许我们在一个序列上迭代。与Python的 ``for`` 语句的情形类似,循环语法是 ``for X in Y`` ,Y是要迭代的序列而X是在每一个特定的循环中使用的变量名称。每一次循环中,模板系统会渲染在 ``{% for %}`` 和 ``{% endfor %}`` 之间的所有内容。 |
893天前 |
|
翻译 |
163#翻译 |
For example, you could use the following to display a list of athletes given a
variable ``athlete_list`` :
|
例如,给定一个运动员列表 ``athlete_list`` 变量,我们可以使用下面的代码来显示这个列表: |
1464天前 |
|
翻译 |
166#翻译 |
Add ``reversed`` to the tag to loop over the list in reverse:
|
给标签增加一个 ``reversed`` 使得该列表被反向迭代: |
1464天前 |
|
翻译 |
169#翻译 |
Its possible to nest ``{% for %}`` tags:
|
可以嵌套使用 ``{% for %}`` 标签: |
1472天前 |
|
翻译 |
172#翻译 |
There is no support for breaking out of a loop before the loop is finished. If you
want to accomplish this, change the variable youre looping over so that it includes
only the values you want to loop over. Similarly, there is no support for a continue
statement that would instruct the loop processor to return immediately to the front
of the loop. (See the section Philosophies and Limitations later in this chapter for
the reasoning behind this design decision.)
|
Django不支持退出循环操作。如果我们想退出循环,可以改变正在迭代的变量,让其仅仅包含需要迭代的项目。同理,Django也不支持continue语句,我们无法让当前迭代操作跳回到循环头部。(请参看本章稍后的理念和限制小节,了解下决定这个设计的背后原因) |
1255天前 |
|
翻译 |
173#翻译 |
The ``{% for %}`` tag sets a magic ``forloop`` template variable within the loop.
This variable has a few attributes that give you information about the progress of
the loop:
|
``{% for %}`` 标签在循环中设置了一个特殊的 ``forloop`` 模板变量。这个变量能提供一些当前循环进展的信息: |
1462天前 |
|
翻译 |
174#翻译 |
``forloop.counter`` is always set to an integer representing the number of times
the loop has been entered. This is one-indexed, so the first time through the
loop, ``forloop.counter`` will be set to ``1`` . Heres an example:
|
``forloop.counter`` 总是一个表示当前循环的执行次数的整数计数器。这个计数器是从1开始的,所以在第一次循环时 ``forloop.counter`` 将会被设置为1。例子如下: |
1463天前 |
|
翻译 |
177#翻译 |
``forloop.counter0`` is like ``forloop.counter`` , except its zero-indexed. Its
value will be set to ``0`` the first time through the loop.
|
``forloop.counter0`` 类似于 ``forloop.counter`` ,但是它是从0计数的。第一次执行循环时这个变量会被设置为0。 |
1462天前 |
|
翻译 |
178#翻译 |
``forloop.revcounter`` is always set to an integer representing the number of
remaining items in the loop. The first time through the loop,
``forloop.revcounter`` will be set to the total number of items in the sequence
youre traversing. The last time through the loop, ``forloop.revcounter`` will be
set to ``1`` .
|
``forloop.revcounter`` 是表示循环中剩余项的整型变量。在循环初次执行时 ``forloop.revcounter`` 将被设置为序列中项的总数。最后一次循环执行中,这个变量将被置1。 |
1462天前 |
|
翻译 |
179#翻译 |
``forloop.revcounter0`` is like ``forloop.revcounter`` , except its
zero-indexed. The first time through the loop, ``forloop.revcounter0`` will be
set to the number of elements in the sequence minus 1. The last time through the
loop, it will be set to ``0`` .
|
``forloop.revcounter0`` 类似于 ``forloop.revcounter`` ,但它以0做为结束索引。在第一次执行循环时,该变量会被置为序列的项的个数减1。在最后一次迭代时,该变量为0。 |
1218天前 |
|
翻译 |
180#翻译 |
``forloop.first`` is a Boolean value set to ``True`` if this is the first time
through the loop. This is convenient for special casing:
|
``forloop.first`` 是一个布尔值。在第一次执行循环时该变量为True,在下面的情形中这个变量是很有用的。 |
1462天前 |
|
翻译 |
183#翻译 |
``forloop.last`` is a Boolean value set to ``True`` if this is the last time
through the loop. A common use for this is to put pipe characters between a list
of links:
|
``forloop.last`` 是一个布尔值;在最后一次执行循环时被置为True。一个常见的用法是在一系列的链接之间放置管道符(|) |
1462天前 |
|
翻译 |
186#翻译 |
``forloop.parentloop`` is a reference to the ``forloop`` object for the *parent*
loop, in case of nested loops. Heres an example:
|
``forloop.parentloop`` 是一个指向当前循环的上一级循环的 ``forloop`` 对象的引用(在嵌套循环的情况下)。例子在此: |
1462天前 |
|
翻译 |
189#翻译 |
The magic ``forloop`` variable is only available within loops. After the template
parser has reached ``{% endfor %}`` , ``forloop`` disappears.
|
``forloop`` 变量仅仅能够在循环中使用,在模板解析器碰到 ``{% endfor %}`` 标签时, ``forloop`` 就不可访问了。 |
1462天前 |
|
翻译 |
190#翻译 |
Context and the forloop Variable
|
Context和forloop变量 |
1464天前 |
|
翻译 |
191#翻译 |
Inside the ``{% for %}`` block, the existing variables are moved out of the way to
avoid overwriting the magic ``forloop`` variable. Django exposes this moved context
in ``forloop.parentloop`` . You generally dont need to worry about this, but if you
supply a template variable named ``forloop`` (though we advise against it), it will
be named ``forloop.parentloop`` while inside the ``{% for %}`` block.
|
在一个 ``{% for %}`` 块中,已存在的变量会被移除,以避免 ``forloop`` 变量被覆盖。Django会把这个变量移动到 ``forloop.parentloop`` 中。通常我们不用担心这个问题,但是一旦我们在模板中定义了 ``forloop`` 这个变量(当然我们反对这样做),在 ``{% for %}`` 块中它会在 ``forloop.parentloop`` 被重新命名。 |
1461天前 |
|
翻译 |
192#翻译 |
ifequal/ifnotequal
..................
|
ifequal/ifnotequal
.................. |
1436天前 |
|
翻译 |
193#翻译 |
The Django template system deliberately is not a full-fledged programming language
and thus does not allow you to execute arbitrary Python statements. (More on this
idea in the section Philosophies and Limitations.) However, its quite a common
template requirement to compare two values and display something if theyre equaland
Django provides an ``{% ifequal %}`` tag for that purpose.
|
Django模板系统压根儿就没想过实现一个全功能的编程语言,所以它不允许我们在模板中执行Python的语句(还是那句话,要了解更多请参看理念和限制小节)。但是比较两个变量的值并且显示一些结果实在是个太常见的需求了,所以Django提供了 ``{% ifequal %}`` 标签供我们使用。 |
1461天前 |
|
翻译 |
194#翻译 |
The ``{% ifequal %}`` tag compares two values and displays everything between ``{%
ifequal %}`` and ``{% endifequal %}`` if the values are equal.
|
``{% ifequal %}`` 标签比较两个值,当他们相同时,显示在 ``{% ifequal %}`` 和 ``{% endifequal %}`` 之中所有的值。 |
1461天前 |
|
翻译 |
195#翻译 |
This example compares the template variables ``user`` and ``currentuser`` :
|
下面的例子比较两个模板变量 ``user`` 和 ``currentuser`` : |
1461天前 |
|
翻译 |
198#翻译 |
The arguments can be hard-coded strings, with either single or double quotes, so the
following is valid:
|
参数可以是硬编码的字符串,随便用单引号或者双引号引起来,所以下列代码都是正确的: |
1167天前 |
|
翻译 |
201#翻译 |
Just like ``{% if %}`` , the ``{% ifequal %}`` tag supports an optional ``{% else
%}`` :
|
和 ``{% if %}`` 类似, ``{% ifequal %}`` 支持可选的 ``{% else%}`` 标签: |
1461天前 |
|
翻译 |
204#翻译 |
Only template variables, strings, integers, and decimal numbers are allowed as
arguments to ``{% ifequal %}`` . These are valid examples:
|
只有模板变量,字符串,整数和小数可以作为 ``{% ifequal %}`` 标签的参数。这些是正确的例子: |
1461天前 |
|
翻译 |
207#翻译 |
Any other types of variables, such as Python dictionaries, lists, or Booleans, cant
be hard-coded in ``{% ifequal %}`` . These are invalid examples:
|
其他的一些类型,例如Python的字典类型、列表类型、布尔类型,不能用在 ``{% ifequal %}`` 中。
下面是些错误的例子: |
1461天前 |
|
翻译 |
210#翻译 |
If you need to test whether something is true or false, use the ``{% if %}`` tags
instead of ``{% ifequal %}`` .
|
如果你需要判断变量是真还是假,请使用 ``{% if %}`` 来替代 ``{% ifequal %}`` 。 |
1461天前 |
|
翻译 |
211#翻译 |
Comments
........
|
注释
........ |
1461天前 |
|
翻译 |
212#翻译 |
Just as in HTML or in a programming language such as Python, the Django template
language allows for comments. To designate a comment, use ``{# #}`` :
|
象HTML和其他的语言例如python一样,Django模板系统也允许注释。
注释使用 ``{# #}`` : |
1461天前 |
|
翻译 |
215#翻译 |
The comment will not be output when the template is rendered.
|
注释的内容不会在模板渲染时输出。 |
1461天前 |
|
翻译 |
216#翻译 |
A comment cannot span multiple lines. This limitation improves template parsing
performance. In the following template, the rendered output will look exactly the
same as the template (i.e., the comment tag will not be parsed as a comment):
|
注释不能跨多行。这个限制是为了提高模板解析的性能。在下面这个模板中,输出结果和模板本身是
完全一样的(也就是说,注释标签并没有被解析为注释): |
1461天前 |
|
翻译 |
219#翻译 |
Filters
'''''''
|
过滤器
''''''' |
1461天前 |
|
翻译 |
220#翻译 |
As explained earlier in this chapter, template filters are simple ways of altering
the value of variables before theyre displayed. Filters look like this:
|
就象本章前面提到的一样,模板过滤器是在变量被显示前修改它的值的一个简单方法。
过滤器看起来是这样的: |
1431天前 |
|
翻译 |
223#翻译 |
This displays the value of the ``{{ name }}`` variable after being filtered through
the ``lower`` filter, which converts text to lowercase. Use a pipe (``|`` ) to apply
a filter.
|
显示的内容是变量 ``{{ name }}`` 被过滤器 ``lower`` 处理后的结果,它功能是转换文本为小写。
使用 ``|`` 来应用过滤器。 |
1482天前 |
|
翻译 |
224#翻译 |
Filters can be *chained* that is, the output of one filter is applied to the next.
Heres a common idiom for escaping text contents, and then converting line breaks to
``<p>`` tags:
|
过滤器可以被 *串联* ,就是说一个过滤器的输出可以被输入到下一个过滤器。这里有一个常用的
需求,先转义文本到HTML,再转换每行到 ``<p>`` 标签: |
1482天前 |
|
翻译 |
227#翻译 |
Some filters take arguments. A filter argument looks like this:
|
有些过滤器有参数。过滤器参数看起来是这样的: |
1482天前 |
|
翻译 |
230#翻译 |
This displays the first 30 words of the ``bio`` variable. Filter arguments are
always in double quotes.
|
这个将显示变量 ``bio`` 的前30个词。过滤器参数总是使用双引号标识。 |
1482天前 |
|
翻译 |
231#翻译 |
The following are a few of the most important filters; Appendix F covers the rest.
|
下面是一些最重要的过滤器;附录F有完整的过滤器列表。 |
1482天前 |
|
翻译 |
232#翻译 |
``addslashes`` : Adds a backslash before any backslash, single quote, or double
quote. This is useful if the produced text is included in a JavaScript string.
|
``addslashes`` : 添加反斜杠到任何反斜杠、单引号或者双引号前面。
这在处理包含JavaScript的文本时是非常有用的。 |
1482天前 |
|
翻译 |
233#翻译 |
``date`` : Formats a ``date`` or ``datetime`` object according to a format
string given in the parameter, for example:
|
``date`` : 按指定的格式字符串参数格式化 ``date`` 或者 ``datetime`` 对象,
范例: |
1482天前 |
|
翻译 |
236#翻译 |
Format strings are defined in Appendix F.
|
格式参数的定义在附录F中。 |
234天前 |
|
翻译 |
237#翻译 |
``escape`` : Escapes ampersands, quotes, and angle brackets in the given string.
This is useful for sanitizing user-submitted data and for ensuring data is valid
XML or XHTML. Specifically, ``escape`` makes these conversions:
|
``escape`` : 转义 &符号,引号,<,> 符号。
这在确保用户提交的数据是有效的XML或XHTML时是非常有用的。
具体上, ``escape`` 做下面这些转换: |
234天前 |
|
翻译 |
238#翻译 |
* Converts ``&`` to ``&``
|
``escape`` : 转义 &符号,引号,<,> 符号。
这在确保用户提交的数据是有效的XML或XHTML时是非常有用的。
具体上, ``escape`` 做下面这些转换: |
234天前 |
|
翻译 |
239#翻译 |
* Converts ``<`` to ``<``
|
* 转换 ``<`` 到 ``<`` |
1482天前 |
|
翻译 |
240#翻译 |
* Converts ``>`` to ``>``
|
* 转换 ``>`` 到 ``>``
|
1482天前 |
|
翻译 |
241#翻译 |
* Converts ``"`` (double quote) to ``"``
|
* 转换 ``"`` (双引号) 到 ``"`` |
1482天前 |
|
翻译 |
242#翻译 |
* Converts ``'`` (single quote) to ``'``
|
* 转换 ``'`` (单引号) 到 ``'`` |
1482天前 |
|
翻译 |
243#翻译 |
``length`` : Returns the length of the value. You can use this on a list or a
string, or any Python object that knows how to determine its length (i.e., any
object that has a ``__len__()`` method).
|
``length`` : 返回变量的长度。你可以对列表或者字符串,或者任何知道怎么测定长度的Python
对象使用这个方法(也就是说,有 ``__len__()`` 方法的对象)。 |
1482天前 |
|
翻译 |
244#翻译 |
Philosophies and Limitations
````````````````````````````
|
理念与局限
```````````````````````````` |
1256天前 |
|
翻译 |
245#翻译 |
Now that youve gotten a feel for the Django template language, we should point out
some of its intentional limitations, along with some philosophies behind why it
works the way it works.
|
现在你已经对Django的模板语言有一些认识了,我们将指出一些特意设置的限制和为什么要这样做
背后的一些设计哲学。 |
1482天前 |
|
翻译 |
246#翻译 |
More than any other component of Web applications, programmer opinions on template
systems vary wildly. The fact that Python alone has dozens, if not hundreds, of open
source template-language implementations supports this point. Each was likely
created because its developer deemed all existing template languages inadequate. (In
fact, it is said to be a rite of passage for a Python developer to write his or her
own template language! If you havent done this yet, consider it. Its a fun
exercise.)
|
相对Web应用中的其他组件,程序员们对模板系统的分歧是最大的。事实上,Python有成十上百的
开放源码的模板语言实现。每个实现都是因为开发者认为现存的模板语言不够用。(事实上,对一个
Python开发者来说,写一个自己的模板语言就象是某种“成人礼”一样!如果你还没有完成一个自己的
模板语言,好好考虑写一个,这是一个非常有趣的锻炼。) |
1482天前 |
|
翻译 |
247#翻译 |
With that in mind, you might be interested to know that Django doesnt require that
you use its template language. Because Django is intended to be a full-stack Web
framework that provides all the pieces necessary for Web developers to be
productive, many times its *more convenient* to use Djangos template system than
other Python template libraries, but its not a strict requirement in any sense. As
youll see in the upcoming section Using Templates in Views, its very easy to use
another template language with Django.
|
明白了这个,你也许有兴趣知道事实上Django并不强制要求你必须使用它的模板语言。因为Django
虽然被设计成一个FULL-Stack的Web框架,它提供了开发者所必需的所有组件,而且在大多数情况
使用Django模板系统会比其他的Python模板库要 *更方便* 一点,但是并不是严格要求你必须使用
它。就象你将在后续的章节中看到的一样,你也可以非常容易的在Django中使用其他的模板语言。 |
1442天前 |
|
翻译 |
248#翻译 |
Still, its clear we have a strong preference for the way Djangos template language
works. The template system has roots in how Web development is done at World Online
and the combined experience of Djangos creators. Here are a few of those
philosophies:
|
虽然如此,很明显,我们对Django模板语言的工作方式有着强烈的偏爱。这个模板语言来源于World Online的开发经验和Django创造者们集体智慧的结晶。下面是关于它的一些设计哲学理念: |
1192天前 |
|
翻译 |
249#翻译 |
*Business logic should be separated from presentation logic* . We see a template
system as a tool that controls presentation and presentation-related logicand
thats it. The template system shouldnt support functionality that goes beyond
this basic goal.
|
*业务逻辑应该和表现逻辑相对分开* 。我们将模板系统视为控制表现及表现相关逻辑的工具,仅此而已。模板系统不应提供超出此基本目标的功能。
|
1256天前 |
|
翻译 |
250#翻译 |
For that reason, its impossible to call Python code directly within Django
templates. All programming is fundamentally limited to the scope of what
template tags can do. It *is* possible to write custom template tags that do
arbitrary things, but the out-of-the-box Django template tags intentionally do
not allow for arbitrary Python code execution.
|
出于这个原因,在 Django 模板中是不可能直接调用 Python 代码的。所有的编程工作基本上都被局限于模板标签的能力范围。当然, *是* 有可能写出自定义的模板标签来完成任意工作,但这些“超范围”的 Django 模板标签有意地不允许执行任何 Python 代码。 |
1256天前 |
|
翻译 |
251#翻译 |
*Syntax should be decoupled from HTML/XML* . Although Djangos template system is
used primarily to produce HTML, its intended to be just as usable for non-HTML
formats, such as plain text. Some other template languages are XML based,
placing all template logic within XML tags or attributes, but Django
deliberately avoids this limitation. Requiring valid XML to write templates
introduces a world of human mistakes and hard-to-understand error messages, and
using an XML engine to parse templates incurs an unacceptable level of overhead
in template processing.
|
*语法不应受到 HTML/XML 的束缚* 。尽管 Django 模板系统主要用于生成 HTML,它还是被有意地设计为可生成非 HTML 格式,如纯文本。一些其它的模板语言是基于 XML 的,将所有的模板逻辑置于 XML 标签与属性之中,而 Django 有意地避开了这种限制。强制要求使用有效 XML 编写模板将会引发大量的人为错误和难以理解的错误信息,而且使用 XML 引擎解析模板也会导致令人无法容忍的模板处理开销。 |
1256天前 |
|
翻译 |
252#翻译 |
*Designers are assumed to be comfortable with HTML code* . The template system
isnt designed so that templates necessarily are displayed nicely in WYSIWYG
editors such as Dreamweaver. That is too severe a limitation and wouldnt allow
the syntax to be as nice as it is. Django expects template authors to be
comfortable editing HTML directly.
|
*假定设计师精通 HTML 编码* 。模板系统的设计意图并不是为了让模板一定能够很好地显示在 Dreamweaver 这样的所见即所得编辑器中。这种限制过于苛刻,而且会使得语法不能像目前这样的完美。Django 要求模板创作人员对直接编辑 HTML 非常熟悉。
|
1256天前 |
|
翻译 |
253#翻译 |
*Designers are assumed not to be Python programmers* . The template system
authors recognize that Web page templates are most often written by *designers*
, not *programmers* , and therefore should not assume Python knowledge.
|
*假定设计师不是 Python 程序员* 。模板系统开发人员认为:网页模板通常由 *设计师* 而不是 *程序员* 编写,因而假定这些人并不掌握 Python 相关知识。 |
1256天前 |
|
翻译 |
254#翻译 |
However, the system also intends to accommodate small teams in which the
templates *are* created by Python programmers. It offers a way to extend the
systems syntax by writing raw Python code. (More on this in Chapter 10.)
|
当然,系统同样也特意地提供了对那些 *由* Python 程序员进行模板制作的小型团队的支持。它提供了一种工作模式,允许通过编写原生 Python 代码进行系统语法拓展。(详见第十章) |
1256天前 |
|
翻译 |
255#翻译 |
*The goal is not to invent a programming language* . The goal is to offer just
enough programming-esque functionality, such as branching and looping, that is
essential for making presentation-related decisions.
|
*目标并不是要发明一种编程语言* 。目标是恰到好处地提供如分支和循环这一类编程式功能,这是进行与表现相关判断的基础。 |
1256天前 |
|
翻译 |
256#翻译 |
As a result of these design philosophies, the Django template language has the
following limitations:
|
采用这些设计理念的结果是导致 Django 模板语言有以下几点限制: |
1256天前 |
|
翻译 |
257#翻译 |
* *A template cannot set a variable or change the value of a variable* . Its
possible to write custom template tags that accomplish these goals (see Chapter
10), but the stock Django template tags do not allow it.
|
* *模板中不能设置变量和改变变量的值* 。可以通过编写自定义模板标签做到这一点(参见第十章),但正宗的 Django 模板标签做不到。 |
1256天前 |
|
翻译 |
258#翻译 |
* *A template cannot call raw Python code* . Theres no way to drop into Python
mode or use raw Python constructs. Again, its possible to write custom template
tags to do this, but the stock Django template tags dont allow it.
|
* *模板中不能调用任何的Python代码* 。不存在转入 Python 模式或使用原生 Python 数据结构的方法。和前面一样,可以编写自定义模板标签来实现这个目标,但正統的 Django 模板标签做不到。 |
1017天前 |
|
翻译 |
259#翻译 |
Using Templates in Views
````````````````````````
|
在视图中使用模板
```````````````````````` |
1482天前 |
|
翻译 |
260#翻译 |
Youve learned the basics of using the template system; now lets use this knowledge
to create a view. Recall the ``current_datetime`` view in ``mysite.views`` , which
we started in the previous chapter. Heres what it looks like:
|
在学习了模板系统的基础之后,现在让我们使用相关知识来创建视图。重新打开我们在前一章在 ``mysite.views`` 中创建的 ``current_datetime`` 视图。以下是其内容: |
1256天前 |
|
翻译 |
263#翻译 |
Lets change this view to use Djangos template system. At first, you might think to
do something like this:
|
让我们用 Django 模板系统来修改该视图。第一步,你可能已经想到了要做下面这样的修改: |
1256天前 |
|
翻译 |
266#翻译 |
Sure, that uses the template system, but it doesnt solve the problems we pointed out
in the introduction of this chapter. Namely, the template is still embedded in the
Python code. Lets fix that by putting the template in a *separate file* , which this
view will load.
|
没错,它确实使用了模板系统,但是并没有解决我们在本章开头所指出的问题。也就是说,模板依然内嵌在 Python 代码之中。让我们将模板置于一个 *单独的文件* 中,并且让视图加载该文件来解决此问题。 |
849天前 |
|
翻译 |
267#翻译 |
You might first consider saving your template somewhere on your filesystem and using
Pythons built-in file-opening functionality to read the contents of the template.
Heres what that might look like, assuming the template was saved as the file
``/home/djangouser/templates/mytemplate.html`` :
|
你可能首先考虑把模板保存在文件系统的某个位置并用 Python 内建的文件操作函数来读取文件内容。假设文件保存在 ``/home/djangouser/templates/mytemplate.html`` 中的话,代码就会像下面这样: |
1256天前 |
|
翻译 |
270#翻译 |
This approach, however, is inelegant for these reasons:
|
然而,基于以下几个原因,该方法还算不上简洁: |
1255天前 |
|
翻译 |
271#翻译 |
* It doesnt handle the case of a missing file. If the file ``mytemplate.html``
doesnt exist or isnt readable, the ``open()`` call will raise an ``IOError``
exception.
|
* 它没有对文件丢失的情况做出处理。如果文件 ``mytemplate.html`` 不存在或者不可读,
``open()`` 函数调用将会引发 ``IOError`` 异常。 |
1256天前 |
|
翻译 |
272#翻译 |
* It hard-codes your template location. If you were to use this technique for
every view function, youd be duplicating the template locations. Not to mention
it involves a lot of typing!
|
* 这里对模板文件的位置进行了硬编码。如果你在每个视图函数都用该技术,就要不断复制这些模板的位置。更不用说还要带来大量的输入工作! |
1256天前 |
|
翻译 |
273#翻译 |
* It includes a lot of boring boilerplate code. Youve got better things to do than
to write calls to ``open()`` , ``fp.read()`` , and ``fp.close()`` each time you
load a template.
|
* 它包含了大量令人生厌的重复代码。与其在每次加载模板时都调用 ``open()`` 、 ``fp.read()`` 和 ``fp.close()`` ,还不如做出更佳选择。 |
1256天前 |
|
翻译 |
274#翻译 |
To solve these issues, well use *template loading* and *template directories* , both
of which are described in the sections that follow.
|
要解决此问题,我们将使用 *模板加载* 和 *模板目录* ,这是我们在接下来的章节中要讨论的两个话题。 |
1256天前 |
|
翻译 |
275#翻译 |
Template Loading
````````````````
|
模板加载
```````````````` |
1482天前 |
|
翻译 |
276#翻译 |
Django provides a convenient and powerful API for loading templates from disk, with
the goal of removing redundancy both in your template-loading calls and in your
templates themselves.
|
为了减少模板加载调用过程及模板本身的冗余代码,Django 提供了一种使用方便且功能强大的 API ,用于从磁盘中加载模板, |
1255天前 |
|
翻译 |
277#翻译 |
In order to use this template-loading API, first youll need to tell the framework
where you store your templates. The place to do this is in your *settings file* .
|
要使用此模板加载API,首先你必须将模板的保存位置告诉框架。该项工作在 *设置文件* 中完成。 |
1255天前 |
|
翻译 |
278#翻译 |
A Django settings file is the place to put configuration for your Django instance
(aka your Django project). Its a simple Python module with module-level variables,
one for each setting.
|
Django 设置文件是存放 Django 实例(也就是 Django 项目)配置的地方。它是一个简单的 Python 模块,其中包含了一些模块级变量,每个都是一项设置。 |
1255天前 |
|
翻译 |
279#翻译 |
When you ran ``django-admin.py startproject mysite`` in Chapter 2, the script
created a default settings file for you, aptly named ``settings.py`` . Have a look
at the files contents. It contains variables that look like this (though not
necessarily in this order):
|
第二章中执行 ``django-admin.py startproject mysite`` 命令时,它为你创建了一个的缺省配置文件,并恰如其分地将其名为 ``settings.py`` 。查看一下该文件内容。其中包含如下变量(但并不一定是这个顺序): |
1255天前 |
|
翻译 |
282#翻译 |
This is pretty self-explanatory; the settings and their respective values are simple
Python variables. And because the settings file is just a plain Python module, you
can do dynamic things such as checking the value of one variable before setting
another. (This also means that you should avoid Python syntax errors in your
settings file.)
|
这里无需更多诠释;设置项与值均为简单的 Python 变量。同时由于配置文件只不过是纯 Python 模块,你可以完成一些动态工作,比如在设置某变量之前检查另一变量的值。(这也意味着你必须避免配置文件出现 Python 语法错误。) |
1255天前 |
|
翻译 |
283#翻译 |
Well cover settings files in depth in Appendix E, but for now, have a look at the
``TEMPLATE_DIRS`` setting. This setting tells Djangos template-loading mechanism
where to look for templates. By default, its an empty tuple. Pick a directory where
youd like to store your templates and add it to ``TEMPLATE_DIRS`` , like so:
|
我们将在附录 E 中详述配置文件,目前而言,仅需关注 ``TEMPLATE_DIRS`` 设置。该设置告诉 Django 的模板加载机制在哪里查找模板。缺省情况下,该设置的值是一个空的元组。选择一个目录用于存放模板并将其添加到 ``TEMPLATE_DIRS`` 中: |
1255天前 |
|
翻译 |
286#翻译 |
There are a few things to note:
|
下面是一些注意事项: |
1482天前 |
|
翻译 |
287#翻译 |
You can specify any directory you want, as long as the directory and templates
within that directory are readable by the user account under which your Web
server runs. If you cant think of an appropriate place to put your templates, we
recommend creating a ``templates`` directory within your Django project (i.e.,
within the ``mysite`` directory you created in Chapter 2, if youve been
following along with this books examples).
|
你可以任意指定想要的目录,只要运行 Web 服务器的用户账号可以读取该目录的子目录和模板文件。如果实在想不出合适的位置来放置模板,我们建议在 Django 项目中创建一个 ``templates`` 目录(也就是说,如果你一直都按本书的范例操作的话,在第二章创建的 ``mysite`` 目录中)。 |
1255天前 |
|
翻译 |
288#翻译 |
Dont forget the comma at the end of the template directory string! Python
requires commas within single-element tuples to disambiguate the tuple from a
parenthetical expression. This is a common newbie gotcha.
|
不要忘记模板目录字符串尾部的逗号!Python 要求单元素元组中必须使用逗号,以此消除与圆括号表达式之间的歧义。这是新手常犯的错误。 |
1255天前 |
|
翻译 |
289#翻译 |
If you want to avoid this error, you can make ``TEMPLATE_DIRS`` a list instead
of a tuple, because single-element lists dont require a trailing comma:
|
想避免此错误的话,你可以将列表而不是元组用作 ``TEMPLATE_DIRS`` ,因为单元素列表并不强制要求以逗号收尾: |
1255天前 |
|
翻译 |
292#翻译 |
A tuple is slightly more semantically correct than a list (tuples cannot be
changed after being created, and nothing should be changing settings once theyve
been read), so we recommend using a tuple for your ``TEMPLATE_DIRS`` setting.
|
从语义上看,元组比列表略显合适(元组在创建之后就不能修改,而配置被读取以后就不应该有任何修改)。因此,我们推荐对 ``TEMPLATE_DIRS`` 设置使用元组。 |
1255天前 |
|
翻译 |
293#翻译 |
If youre on Windows, include your drive letter and use Unix-style forward
slashes rather than backslashes, as follows:
|
如果使用的是 Windows 平台,请包含驱动器符号并使用Unix风格的斜杠(/)而不是反斜杠(\\),就像下面这样: |
1255天前 |
|
翻译 |
296#翻译 |
Its simplest to use absolute paths (i.e., directory paths that start at the root
of the filesystem). If you want to be a bit more flexible and decoupled, though,
you can take advantage of the fact that Django settings files are just Python
code by constructing the contents of ``TEMPLATE_DIRS`` dynamically, for example:
|
最省事的方式是使用绝对路径(即从文件系统根目录开始的目录路径)。如果想要更灵活一点并减少一些负面干扰,可利用 Django 配置文件就是 Python 代码这一点来动态构建 ``TEMPLATE_DIRS`` 的内容,如: |
1255天前 |
|
翻译 |
299#翻译 |
This example uses the magic Python variable ``__file__`` , which is
automatically set to the file name of the Python module in which the code lives.
|
这个例子使用了神奇的 Python 内部变量 ``__file__`` ,该变量被自动设置为代码所在的 Python 模块文件名。 |
1255天前 |
|
翻译 |
300#翻译 |
With ``TEMPLATE_DIRS`` set, the next step is to change the view code to use Djangos
template-loading functionality rather than hard-coding the template paths. Returning
to our ``current_datetime`` view, lets change it like so:
|
完成 ``TEMPLATE_DIRS`` 设置后,下一步就是修改视图代码,让它使用 Django 模板加载功能而不是对模板路径硬编码。返回 ``current_datetime`` 视图,进行如下修改: |
1255天前 |
|
翻译 |
303#翻译 |
In this example, were using the function ``django.template.loader.get_template()``
rather than loading the template from the filesystem manually. The
``get_template()`` function takes a template name as its argument, figures out where
the template lives on the filesystem, opens that file, and returns a compiled
``Template`` object.
|
此范例中,我们使用了函数 ``django.template.loader.get_template()`` ,而不是手动从文件系统加载模板。该 ``get_template()`` 函数以模板名称为参数,在文件系统中找出模块的位置,打开文件并返回一个编译好的 ``Template`` 对象。 |
1255天前 |
|
翻译 |
304#翻译 |
If ``get_template()`` cannot find the template with the given name, it raises a
``TemplateDoesNotExist`` exception. To see what that looks like, fire up the Django
development server again, as in Chapter 3, by running ``python manage.py runserver``
within your Django projects directory. Then, point your browser at the page that
activates the ``current_datetime`` view (e.g., ``http://127.0.0.1:8000/time/`` ).
Assuming your ``DEBUG`` setting is set to ``True`` and you havent yet created a
``current_datetime.html`` template, you should see a Django error page highlighting
the ``TemplateDoesNotExist`` error.
|
如果 ``get_template()`` 找不到给定名称的模板,将会引发一个 ``TemplateDoesNotExist`` 异常。要了解究竟会发生什么,让我们按照第三章内容,在 Django 项目目录中运行 ``python manage.py runserver`` 命令,再次启动Django开发服务器。。然后,用浏览器访问页面(如: ``http://127.0.0.1:8000/time/`` ) 激活 ``current_datetime`` 视图。假如 ``DEBUG`` 设置为 ``True`` 而又未创建 ``current_datetime.html`` 模板,你将会看到 ``TemplateDoesNotExist`` 错误信息页面。 |
1255天前 |
|
翻译 |
305#翻译 |
.. image:: http://new-media.djangobook.com/content/en/1.0/chapter04/missing_template.png
:alt: Screenshot of a TemplateDoesNotExist error.
|
.. image:: http://new-media.djangobook.com/content/en/1.0/chapter04/missing_template.png
:alt: Screenshot of a TemplateDoesNotExist error. |
1436天前 |
|
翻译 |
307#翻译 |
Figure 4-1: The error page shown when a template cannot be found.
|
图 4-1: 无法找到模板时的出错页面 |
1255天前 |
|
翻译 |
308#翻译 |
This error page is similar to the one we explained in Chapter 3, with one additional
piece of debugging information: a Template-loader postmortem section. This section
tells you which templates Django tried to load, along with the reason each attempt
failed (e.g., File does not exist). This information is invaluable when youre trying
to debug template-loading errors.
|
该页面与我们在第三章解释过的错误页面相似,只不过多了一块调试信息区:模板加载器事后检查区。该区域显示 Django 要加载哪个模板、每次尝试出错的原因(如:文件不存在等)。在调试模板加载错误时,这些信息的价值是不可估量的。 |
1255天前 |
|
翻译 |
309#翻译 |
As you can probably tell from the error messages found in the Figure 4-1, Django
attempted to find the template by combining the directory in the ``TEMPLATE_DIRS``
setting with the template name passed to ``get_template()`` . So if your
``TEMPLATE_DIRS`` contains ``'/home/django/templates'`` , Django looks for the file
``'/home/django/templates/current_datetime.html'`` . If ``TEMPLATE_DIRS`` contains
more than one directory, each is checked until the template is found or theyve all
been checked.
|
正如你从图 4-1 中的错误信息中所看到,Django 尝试通过组合 ``TEMPLATE_DIRS`` 设置以及传递给 ``get_template()`` 的模板名称来查找模板。因此如果 ``TEMPLATE_DIRS`` 为 ``'/home/django/templates'`` ,Django 将会
查找 ``'/home/django/templates/current_datetime.html'`` 。如果 ``TEMPLATE_DIRS`` 包含多个目录,它将会查找每个目录直至找到模板或找遍所有目录。 |
1255天前 |
|
翻译 |
310#翻译 |
Moving along, create the ``current_datetime.html`` file within your template
directory using the following template code:
|
接下来,在模板目录中创建包括以下模板代码 ``current_datetime.html`` 文件: |
1255天前 |
|
翻译 |
313#翻译 |
Refresh the page in your Web browser, and you should see the fully rendered page.
|
在网页浏览器中刷新该页,你将会看到完整解析后的页面。 |
1254天前 |
|
翻译 |
314#翻译 |
render_to_response()
''''''''''''''''''''
|
render_to_response()
'''''''''''''''''''' |
1482天前 |
|
翻译 |
315#翻译 |
Because its such a common idiom to load a template, fill a ``Context`` , and return
an ``HttpResponse`` object with the result of the rendered template, Django provides
a shortcut that lets you do those things in one line of code. This shortcut is a
function called ``render_to_response()`` , which lives in the module
``django.shortcuts`` . Most of the time, youll be using ``render_to_response()``
rather than loading templates and creating ``Context`` and ``HttpResponse`` objects
manually.
|
由于加载模板、填充 ``context`` 、将经解析的模板结果返回为 ``HttpResponse`` 对象这一系列操作实在太常用了,Django 提供了一条仅用一行代码就完成所有这些工作的捷径。该捷径就是位于 ``django.shortcuts`` 模块中名为 ``render_to_response()`` 的函数。大多数时候,你将使用 ``render_to_response()`` ,而不是手动加载模板、创建 ``Context`` 和 ``HttpResponse`` 对象。 |
1255天前 |
|
翻译 |
316#翻译 |
Heres the ongoing ``current_datetime`` example rewritten to use
``render_to_response()`` :
|
下面就是使用 ``render_to_response()`` 重新编写过的 ``current_datetime`` 范例。 |
1255天前 |
|
翻译 |
319#翻译 |
What a difference! Lets step through the code changes:
|
大变样了!让我们逐句看看代码发生的变化: |
1254天前 |
|
翻译 |
320#翻译 |
* We no longer have to import ``get_template`` , ``Template`` , ``Context`` , or
``HttpResponse`` . Instead, we import ``django.shortcuts.render_to_response`` .
The ``import datetime`` remains.
|
* 我们不再需要导入 ``get_template`` 、 ``Template`` 、 ``Context`` 和 ``HttpResponse`` 。相反,我们导入 ``django.shortcuts.render_to_response`` 。 ``import datetime`` 继续保留. |
1255天前 |
|
翻译 |
321#翻译 |
* Within the ``current_datetime`` function, we still calculate ``now`` , but the
template loading, context creation, template rendering, and ``HttpResponse``
creation is all taken care of by the ``render_to_response()`` call. Because
``render_to_response()`` returns an ``HttpResponse`` object, we can simply
``return`` that value in the view.
|
* 在 ``current_datetime`` 函数中,我们仍然进行 ``now`` 计算,但模板加载、上下文创建、模板解析和 ``HttpResponse`` 创建工作均在对 ``render_to_response()`` 的调用中完成了。由于 ``render_to_response()`` 返回 ``HttpResponse`` 对象,因此我们仅需在视图中 ``return`` 该值。 |
1254天前 |
|
翻译 |
322#翻译 |
The first argument to ``render_to_response()`` should be the name of the template to
use. The second argument, if given, should be a dictionary to use in creating a
``Context`` for that template. If you dont provide a second argument,
``render_to_response()`` will use an empty dictionary.
|
``render_to_response()`` 的第一个参数必须是要使用的模板名称。如果要给定第二个参数,那么该参数必须是为该模板创建 ``Context`` 时所使用的字典。如果不提供第二个参数, ``render_to_response()`` 使用一个空字典。 |
1254天前 |
|
翻译 |
323#翻译 |
The locals() Trick
''''''''''''''''''
|
locals() 技巧
''''''''''''''''''
|
1482天前 |
|
翻译 |
324#翻译 |
Consider our latest incarnation of ``current_datetime`` :
|
思考一下我们对 ``current_datetime`` 的最后一次赋值: |
1254天前 |
|
翻译 |
327#翻译 |
Many times, as in this example, youll find yourself calculating some values, storing
them in variables (e.g., ``now`` in the preceding code), and sending those variables
to the template. Particularly lazy programmers should note that its slightly
redundant to have to give names for temporary variables *and* give names for the
template variables. Not only is it redundant, but also its extra typing.
|
很多时候,就像在这个范例中那样,你发现自己一直在计算某个变量,保存结果到变量中(比如:前面代码中的 ``now`` ),然后将这些变量发送给模板。特别懒的程序员可能注意到给这些临时变量 *和* 模板变量命名显得有点多余。不但多余,而且还要进行额外的键盘输入。 |
1254天前 |
|
翻译 |
328#翻译 |
So if youre one of those lazy programmers and you like keeping code particularly
concise, you can take advantage of a built-in Python function called ``locals()`` .
It returns a dictionary mapping all local variable names to their values. Thus, the
preceding view could be rewritten like so:
|
如果你是个喜欢偷懒的程序员并想让代码看起来更加简明,可以利用 Python 的内建函数 ``locals()`` 。它返回的字典对所有局部变量的名称与值进行映射。因此,前面的视图可以重写成下面这个样子: |
1254天前 |
|
翻译 |
331#翻译 |
Here, instead of manually specifying the context dictionary as before, we pass the
value of ``locals()`` , which will include all variables defined at that point in
the functions execution. As a consequence, weve renamed the ``now`` variable to
``current_date`` , because thats the variable name that the template expects. In
this example, ``locals()`` doesnt offer a *huge* improvement, but this technique can
save you some typing if you have several template variables to defineor if youre
lazy.
|
在此,我们没有像之前那样手工指定 context 字典,而是传入了 ``locals()`` 的值,它囊括了函数执行到该时间点时所定义的一切变量。因此,我们将 ``now`` 变量重命名为 ``current_date`` ,因为那才是模板所预期的变量名称。在本例中, ``locals()`` 并没有带来多 *大* 的改进,但是如果有多个模板变量要界定而你又想偷懒,这种技术可以减少一些键盘输入。 |
1046天前 |
|
翻译 |
332#翻译 |
One thing to watch out for when using ``locals()`` is that it includes *every* local
variable, which may comprise more variables than you actually want your template to
have access to. In the previous example, ``locals()`` will also include ``request``
. Whether this matters to you depends on your application.
|
使用 ``locals()`` 时要注意是它将包括 *所有* 的局部变量,组成它的变量可能比你想让模板访问的要多。在前例中, ``locals()`` 还包含了 ``request`` 。对此如何取舍取决你的应用程序。 |
1254天前 |
|
翻译 |
333#翻译 |
A final thing to consider is that ``locals()`` incurs a small bit of overhead,
because when you call it, Python has to create the dictionary dynamically. If you
specify the context dictionary manually, you avoid this overhead.
|
最后要考虑的是在你调用 ``locals()`` 时,Python 必须得动态创建字典,因此它会带来一点额外的开销。如果手动指定 context 字典,则可以避免这种开销。 |
1254天前 |
|
翻译 |
334#翻译 |
Subdirectories in get_template()
''''''''''''''''''''''''''''''''
|
get_template()中使用子目录
'''''''''''''''''''''''''''''''' |
1482天前 |
|
翻译 |
335#翻译 |
It can get unwieldy to store all of your templates in a single directory. You might
like to store templates in subdirectories of your template directory, and thats
fine. In fact, we recommend doing so; some more advanced Django features (such as
the generic views system, which we cover in Chapter 9) expect this template layout
as a default convention.
|
把所有的模板都存放在一个目录下可能会让事情变得难以掌控。你可能会考虑把模板存放在你模板目录的子目录中,这非常好。事实上,我们推荐这样做;一些Django的高级特性(例如将在第九章讲到的通用视图系统)的缺省约定就是期望使用这种模板布局。 |
1254天前 |
|
翻译 |
336#翻译 |
Storing templates in subdirectories of your template directory is easy. In your
calls to ``get_template()`` , just include the subdirectory name and a slash before
the template name, like so:
|
把模板存放于模板目录的子目录中是件很轻松的事情。只需在调用 ``get_template()`` 时,把子目录名和一条斜杠添加到模板名称之前,如: |
1254天前 |
|
翻译 |
339#翻译 |
Because ``render_to_response()`` is a small wrapper around ``get_template()`` , you
can do the same thing with the first argument to ``render_to_response()`` .
|
由于 ``render_to_response()`` 只是对 ``get_template()`` 的简单封装, 你可以对 ``render_to_response()`` 的第一个参数做相同处理。 |
1254天前 |
|
翻译 |
340#翻译 |
Theres no limit to the depth of your subdirectory tree. Feel free to use as many as
you like.
|
对子目录树的深度没有限制,你想要多少层都可以。 |
1254天前 |
|
翻译 |
341#翻译 |
Note
|
注意 |
1482天前 |
|
翻译 |
342#翻译 |
Windows users, be sure to use forward slashes rather than backslashes.
``get_template()`` assumes a Unix-style file name designation.
|
Windows用户必须使用斜杠而不是反斜杠。 ``get_template()`` 假定的是 Unix 风格的文件名符号约定。 |
1254天前 |
|
翻译 |
343#翻译 |
The ``include`` Template Tag
''''''''''''''''''''''''''''
|
``include`` 模板标签
''''''''''''''''''''''''''''
|
1482天前 |
|
翻译 |
344#翻译 |
Now that weve covered the template-loading mechanism, we can introduce a built-in
template tag that takes advantage of it: ``{% include %}`` . This tag allows you to
include the contents of another template. The argument to the tag should be the name
of the template to include, and the template name can be either a variable or a
hard-coded (quoted) string, in either single or double quotes. Anytime you have the
same code in multiple templates, consider using an ``{% include %}`` to remove the
duplication.
|
在讲解了模板加载机制之后,我们再介绍一个利用该机制的内建模板标签: ``{% include %}`` 。该标签允许在(模板中)包含其它的模板的内容。标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引号硬编码的字符串。每当在多个模板中出现相同的代码时,就应该考虑是否要使用 ``{% include %}`` 来减少重复。 |
1254天前 |
|
翻译 |
345#翻译 |
These two examples include the contents of the template ``nav.html`` . The examples
are equivalent and illustrate that either single or double quotes are allowed:
|
下面这两个例子都包含了 ``nav.html`` 模板。两个例子的作用完全相同,只不过是为了说明单、双引号都可以通用。 |
1254天前 |
|
翻译 |
348#翻译 |
This example includes the contents of the template ``includes/nav.html`` :
|
下面的例子包含了 ``includes/nav.html`` 模板的内容: |
1254天前 |
|
翻译 |
351#翻译 |
This example includes the contents of the template whose name is contained in the
variable ``template_name`` :
|
下面的例子包含了以变量 ``template_name`` 的值为名称的模板内容: |
1254天前 |
|
翻译 |
354#翻译 |
As in ``get_template()`` , the file name of the template is determined by adding the
template directory from ``TEMPLATE_DIRS`` to the requested template name.
|
和在 ``get_template()`` 中一样, 对模板的文件名进行判断时会在所调取的模板名称之前加上来自 ``TEMPLATE_DIRS`` 的模板目录。 |
1254天前 |
|
翻译 |
355#翻译 |
Included templates are evaluated with the context of the template thats including
them.
|
所包含的模板执行时的 context 和包含它们的模板是一样的。 |
1254天前 |
|
翻译 |
356#翻译 |
If a template with the given name isnt found, Django will do one of two things:
|
如果未找到给定名称的模板文件,Django 会从以下两件事情中择一而为之: |
1254天前 |
|
翻译 |
357#翻译 |
* If ``DEBUG`` is set to ``True`` , youll see the ``TemplateDoesNotExist``
exception on a Django error page.
|
* 如果 ``DEBUG`` 设置为 ``True`` ,你将会在 Django 错误信息页面看到 ``TemplateDoesNotExist`` 异常。 |
1254天前 |
|
翻译 |
358#翻译 |
* If ``DEBUG`` is set to ``False`` , the tag will fail silently, displaying
nothing in the place of the tag.
|
* 如果 ``DEBUG`` 设置为 ``False`` ,该标签不会引发错误信息,在标签位置不显示任何东西。 |
1254天前 |
|
翻译 |
359#翻译 |
Template Inheritance
````````````````````
|
模板继承
````````````````````
|
1481天前 |
|
翻译 |
360#翻译 |
Our template examples so far have been tiny HTML snippets, but in the real world,
youll be using Djangos template system to create entire HTML pages. This leads to a
common Web development problem: across a Web site, how does one reduce the
duplication and redundancy of common page areas, such as sitewide navigation?
|
到目前为止,我们的模板范例都只是些零星的 HTML 片段,但在实际应用中,你将用 Django 模板系统来创建整个 HTML 页面。这就带来一个常见的 Web 开发问题:在整个网站中,如何减少共用页面区域(比如站点导航)所引起的重复和冗余代码? |
1254天前 |
|
翻译 |
361#翻译 |
A classic way of solving this problem is to use *server-side includes* , directives
you can embed within your HTML pages to include one Web page inside another. Indeed,
Django supports that approach, with the ``{% include %}`` template tag just
described. But the preferred way of solving this problem with Django is to use a
more elegant strategy called *template inheritance* .
|
解决该问题的传统做法是使用 *服务器端的 includes* ,你可以在 HTML 页面中使用该指令将一个网页嵌入到另一个中。事实上, Django 通过刚才讲述的 ``{% include %}`` 支持了这种方法。但是用 Django 解决此类问题的首选方法是使用更加简洁的策略—— *模板继承* 。 |
1254天前 |
|
翻译 |
362#翻译 |
In essence, template inheritance lets you build a base skeleton template that
contains all the common parts of your site and defines blocks that child templates
can override.
|
本质上来说,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载。 |
1254天前 |
|
翻译 |
363#翻译 |
Lets see an example of this by creating a more complete template for our
``current_datetime`` view, by editing the ``current_datetime.html`` file:
|
让我们通过修改 ``current_datetime.html`` 文件,为 ``current_datetime`` 创建一个更加完整的模板来体会一下这种做法: |
1254天前 |
|
翻译 |
366#翻译 |
That looks just fine, but what happens when we want to create a template for another
viewsay, the ``hours_ahead`` view from Chapter 3? If we want again to make a nice,
valid, full HTML template, wed create something like:
|
这看起来很棒,但如果我们要为第三章的 ``hours_ahead`` 视图创建另一个模板会发生什么事情呢?如果我们再次创建一个漂亮、有效且完整的 HTML 模板,我们可能会创建出下面这样的东西: |
1254天前 |
|
翻译 |
369#翻译 |
Clearly, weve just duplicated a lot of HTML. Imagine if we had a more typical site,
including a navigation bar, a few style sheets, perhaps some JavaScriptwed end up
putting all sorts of redundant HTML into each template.
|
很明显,我们刚才重复了大量的 HTML 代码。想象一下,如果有一个更典型的网站,它有导航条、样式表,可能还有一些 JavaScript 代码,事情必将以向每个模板填充各种冗余的 HTML 而告终。 |
1254天前 |
|
翻译 |
370#翻译 |
The server-side include solution to this problem is to factor out the common bits in
both templates and save them in separate template snippets, which are then included
in each template. Perhaps youd store the top bit of the template in a file called
``header.html`` :
|
解决这个问题的服务器端 include 方案是找出两个模板中的共同部分,将其保存为不同的模板片段,然后在每个模板中进行 include。也许你会把模板头部的一些代码保存为 ``header.html`` 文件: |
1254天前 |
|
翻译 |
373#翻译 |
And perhaps youd store the bottom bit in a file called ``footer.html`` :
|
你可能会把底部保存到文件 ``footer.html`` : |
1254天前 |
|
翻译 |
376#翻译 |
With an include-based strategy, headers and footers are easy. Its the middle ground
thats messy. In this example, both pages feature a title ``<h1>My helpful timestamp
site</h1>`` but that title cant fit into ``header.html`` because the ``<title>`` on
both pages is different. If we included the ``<h1>`` in the header, wed have to
include the ``<title>`` , which wouldnt allow us to customize it per page. See where
this is going?
|
对基于 include 的策略,头部和底部的包含很简单。麻烦的是中间部分。在此范例中,每个页面都有一个 ``<h1>My helpful timestamp site</h1>`` 标题,但是这个标题不能放在 ``header.html`` 中,因为每个页面的 ``<title>`` 是不同的。如果我们将 ``<h1>`` 包含在头部,我们就不得不包含 ``<title>`` ,但这样又不允许在每个页面对它进行定制。何去何从呢? |
1254天前 |
|
翻译 |
377#翻译 |
Djangos template inheritance system solves these problems. You can think of it as an
inside-out version of server-side includes. Instead of defining the snippets that
are *common* , you define the snippets that are *different* .
|
Django 的模板继承系统解决了这些问题。你可以将其视为服务器端 include 的逆向思维版本。你可以对那些 *不同* 的代码段进行定义,而不是 *共同* 代码段。 |
1254天前 |
|
翻译 |
378#翻译 |
The first step is to define a *base template* a skeleton of your page that *child
templates* will later fill in. Heres a base template for our ongoing example:
|
第一步是定义 *基础模板* , 该框架之后将由 *子模板* 所继承。以下是我们目前所讲述范例的基础模板: |
1254天前 |
|
翻译 |
381#翻译 |
This template, which well call ``base.html`` , defines a simple HTML skeleton
document that well use for all the pages on the site. Its the job of child templates
to override, or add to, or leave alone the contents of the blocks. (If youre
following along at home, save this file to your template directory.)
|
这个叫做 ``base.html`` 的模板定义了一个简单的 HTML 框架文档,我们将在本站点的所有页面中使用。子模板的作用就是重载、添加或保留那些块的内容。(如果一直按我们的范例做话,请将此文件保存到模板目录。) |
1254天前 |
|
翻译 |
382#翻译 |
Were using a template tag here that you havent seen before: the ``{% block %}`` tag.
All the ``{% block %}`` tags do is tell the template engine that a child template
may override those portions of the template.
|
我们使用一个以前没有见过的模板标签: ``{% block %}`` 。
所有的 ``{% block %}`` 标签告诉模板引擎,子模板可以重载这些部分。 |
335天前 |
|
翻译 |
383#翻译 |
Now that we have this base template, we can modify our existing
``current_datetime.html`` template to use it:
|
现在我们已经有了一个基本模板,我们可以修改 ``current_datetime.html`` 模板来
使用它: |
1482天前 |
|
翻译 |
386#翻译 |
While were at it, lets create a template for the ``hours_ahead`` view from Chapter
3. (If youre following along with code, well leave it up to you to change
``hours_ahead`` to use the template system.) Heres what that would look like:
|
再为 ``hours_ahead`` 视图创建一个模板,看起来是这样的: |
1482天前 |
|
翻译 |
389#翻译 |
Isnt this beautiful? Each template contains only the code thats *unique* to that
template. No redundancy needed. If you need to make a site-wide design change, just
make the change to ``base.html`` , and all of the other templates will immediately
reflect the change.
|
看起来很漂亮是不是?每个模板只包含对自己而言 *独一无二* 的代码。无需多余的部分。如果想进行站点级的设计修改,仅需修改 ``base.html`` ,所有其它模板会立即反映出所作修改。 |
1254天前 |
|
翻译 |
390#翻译 |
Heres how it works. When you load the template ``current_datetime.html`` , the
template engine sees the ``{% extends %}`` tag, noting that this template is a child
template. The engine immediately loads the parent templatein this case,
``base.html`` .
|
以下是其工作方式。在加载 ``current_datetime.html`` 模板时,模板引擎发现了 ``{% extends %}`` 标签, 注意到该模板是一个子模板。模板引擎立即装载其父模板,即本例中的 ``base.html`` 。 |
1254天前 |
|
翻译 |
391#翻译 |
At that point, the template engine notices the three ``{% block %}`` tags in
``base.html`` and replaces those blocks with the contents of the child template. So,
the title weve defined in ``{% block title %}`` will be used, as will the ``{% block
content %}`` .
|
此时,模板引擎注意到 ``base.html`` 中的三个 ``{% block %}`` 标签,并用子模板的内容替换这些 block 。因此,引擎将会使用我们在 ``{ block title %}`` 中定义的标题,对 ``{% block content %}`` 也是如此。 |
1254天前 |
|
翻译 |
392#翻译 |
Note that since the child template doesnt define the ``footer`` block, the template
system uses the value from the parent template instead. Content within a ``{% block
%}`` tag in a parent template is always used as a fallback.
|
注意由于子模板并没有定义 ``footer`` 块,模板系统将使用在父模板中定义的值。父模板 ``{% block %}`` 标签中的内容总是被当作一条退路。 |
1254天前 |
|
翻译 |
393#翻译 |
Inheritance doesnt affect the way the context works, and you can use as many levels
of inheritance as needed. One common way of using inheritance is the following
three-level approach:
|
继承并不改变 context 的工作方式,而且你可以按照需要使用多层继承。使用继承的一种常见方式是下面的三层法: |
1254天前 |
|
翻译 |
394#翻译 |
1. Create a ``base.html`` template that holds the main look and feel of your site.
This is the stuff that rarely, if ever, changes.
|
1. 创建 ``base.html`` 模板,在其中定义站点的主要外观感受。这些都是不常修改甚至从不修改的部分。
|
1254天前 |
|
翻译 |
395#翻译 |
2. Create a ``base_SECTION.html`` template for each section of your site (e.g.,
``base_photos.html`` and ``base_forum.html`` ). These templates extend
``base.html`` and include section-specific styles/design.
|
2. 为网站的每个区域创建 ``base_SECTION.html`` 模板(例如, ``base_photos.html`` 和 ``base_forum.html`` )。这些模板对 ``base.html`` 进行拓展,并包含区域特定的风格与设计。 |
1254天前 |
|
翻译 |
396#翻译 |
3. Create individual templates for each type of page, such as a forum page or a
photo gallery. These templates extend the appropriate section template.
|
3. 为每种类型的页面创建独立的模板,例如论坛页面或者图片库。这些模板拓展相应的区域模板。 |
1254天前 |
|
翻译 |
397#翻译 |
This approach maximizes code reuse and makes it easy to add items to shared areas,
such as section-wide navigation.
|
这个方法可最大限度地重用代码,并使得向公共区域(如区域级的导航)添加内容成为一件轻松的工作。 |
1254天前 |
|
翻译 |
398#翻译 |
Here are some tips for working with template inheritance:
|
以下是使用模板继承的一些诀窍: |
1254天前 |
|
翻译 |
399#翻译 |
* If you use ``{% extends %}`` in a template, it must be the first template tag in
that template. Otherwise, template inheritance wont work.
|
* 如果在模板中使用 ``{% extends %}`` ,必须保证其为模板中的第一个模板标记。否则,模板继承将不起作用。 |
1254天前 |
|
翻译 |
400#翻译 |
* Generally, the more ``{% block %}`` tags in your base templates, the better.
Remember, child templates dont have to define all parent blocks, so you can fill
in reasonable defaults in a number of blocks, and then define only the ones you
need in the child templates. Its better to have more hooks than fewer hooks.
|
* 一般来说,基础模板中的 ``{% block %}`` 标签越多越好。记住,子模板不必定义父模板中所有的代码块,因此你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。俗话说,钩子越多越好。 |
1254天前 |
|
翻译 |
401#翻译 |
* If you find yourself duplicating code in a number of templates, it probably
means you should move that code to a ``{% block %}`` in a parent template.
|
* 如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个 ``{% block %}`` 中。
|
1254天前 |
|
翻译 |
402#翻译 |
* If you need to get the content of the block from the parent template, the ``{{
block.super }}`` variable will do the trick. This is useful if you want to add
to the contents of a parent block instead of completely overriding it.
|
* 如果需要获得父模板中代码块的内容,可以使用 ``{{ block.super }}`` 变量。如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。 |
1254天前 |
|
翻译 |
403#翻译 |
* You may not define multiple ``{% block %}`` tags with the same name in the same
template. This limitation exists because a block tag works in both directions.
That is, a block tag doesnt just provide a hole to fill, it also defines the
content that fills the hole in the *parent* . If there were two similarly named
``{% block %}`` tags in a template, that templates parent wouldnt know which one
of the blocks content to use.
|
* 不可同一个模板中定义多个同名的 ``{% block %}`` 。存在这样的限制是因为block 标签的工作方式是双向的。也就是说,block 标签不仅挖了一个要填的坑,也定义了在 *父* 模板中这个坑所填充的内容。如果模板中出现了两个相同名称的 ``{% block %}`` 标签,父模板将无从得知要使用哪个块的内容。 |
1254天前 |
|
翻译 |
404#翻译 |
* The template name you pass to ``{% extends %}`` is loaded using the same method
that ``get_template()`` uses. That is, the template name is appended to your
``TEMPLATE_DIRS`` setting.
|
* ``{% extends %}`` 对所传入模板名称使用的加载方法和 ``get_template()`` 相同。也就是说,会将模板名称被添加到 ``TEMPLATE_DIRS`` 设置之后。 |
1173天前 |
|
翻译 |
405#翻译 |
* In most cases, the argument to ``{% extends %}`` will be a string, but it can
also be a variable, if you dont know the name of the parent template until
runtime. This lets you do some cool, dynamic stuff.
|
* 多数情况下, ``{% extends %}`` 的参数应该是字符串,但是如果直到运行时方能确定父模板名,这个参数也可以是个变量。这使得你能够实现一些很酷的动态功能。 |
1254天前 |
|
翻译 |
406#翻译 |
Whats next?
```````````
|
接下来?
``````````` |
1454天前 |
|
翻译 |
407#翻译 |
Most modern Web sites are *database-driven* : the content of the Web site is stored
in a relational database. This allows a clean separate of data and logic (in the
same way views and templates allow the separation of logic and display.)
|
时下大多数网站都是 *数据库驱动* 的:网站的内容都是存储在关系型数据库中。这使得数据和逻辑能够彻底地分开(视图和模板也以同样方式对逻辑和显示进行了分隔。) |
1254天前 |
|
翻译 |
408#翻译 |
The next chapter covers the tools Django gives you to interact with a database.
|
在下一章里将讲述 Django 提供的数据库交互工具。 |
1254天前 |
|
翻译 |