第四章 模板

对标题的评论会显示在这里

在前一章中,你可能已经注意到我们在例子视图中返回文本的方式有点特别。 也就是说,HTML被直接硬编码在 Python 代码之中。

对这一段的评论会显示在这里
def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
objectjava 05-25 06:24

翻的太全了。我都感动+激动了

balotelli 09-04 06:19

巴神到此一游

匿名读者 03-09 07:25

地地道道

tunzao 05-24 06:09

辛苦啦。

特里 09-02 08:06

译者好人,好人一生平安。

dd 10-17 10:16

译者好人,好人一生平安

陈Sir 10-31 09:24

排版和字体很有问题,看得很累,尤其是代码区,没有英文原版的好 另外可以参考一下csdn的,看得舒服一些 http://blog.csdn.net/cpk154505/article/details/8825277

周波 06-13 10:17

译者辛苦了,好人一生平安

Immanuel 09-25 02:04

译者好人,好人一生平安

不满 06-20 09:15

感谢译者

匿名读者 11-24 10:43

感谢

对这一段的评论会显示在这里

尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不是一个好主意。 让我们来看一下为什么:

kuber 12-31 07:25

technique 建议翻成"方法", 不是"技术"

对这一段的评论会显示在这里
  • 对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。
  • Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。
  • 程序员编写 Python代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。
mr.liu 05-21 06:31

这段话我喜欢。

yazhou 03-10 09:39

典型的MVC

对这一段的评论会显示在这里

基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式,这就是本章要具体讨论的问题。

对这一段的评论会显示在这里

模板系统基本知识

1 02-05 09:38

1

对这一段的评论会显示在这里

模板是一个文本,用于分离文档的表现形式和内容。 模板定义了占位符以及各种用于规范文档该如何显示的各部分基本逻辑(模板标签)。 模板通常用于产生HTML,但是Django的模板也能产生任何基于文本格式的文档。

对这一段的评论会显示在这里

让我们从一个简单的例子模板开始。 该模板描述了一个向某个与公司签单人员致谢 HTML 页面。 可将其视为一个格式信函:

对这一段的评论会显示在这里
<html>
<head><title>Ordering notice</title></head>

<body>

<h1>Ordering notice</h1>

<p>Dear {{ person_name }},</p>

<p>Thanks for placing an order from {{ company }}. It's scheduled to
ship on {{ ship_date|date:"F j, Y" }}.</p>

<p>Here are the items you've ordered:</p>

<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 %}

<p>Sincerely,<br />{{ company }}</p>

</body>
</html>
bjyinxm 06-20 12:22

{% if **** %} 这种方式让我想起了jsp

boss212 11-14 02:29

倒数第四句,是用<br>吧,怎么会是<br/>呢?

looly 01-20 04:48

re:boss212 在 HTML 中,<br> 标签没有结束标签。 在 XHTML 中,<br> 标签必须被正确地关闭,比如这样:<br />。

ivy 04-16 07:41

为什么会是{{}}方式?两层括号是为了什么

ivy 04-16 08:14

知道{{}}是干什么的了

nicholas 09-24 03:00

有点像jsp

andywu1206 11-08 23:53

1.请问 {% for item in item_list %} 与 {{person_name}} 有什么区别? 2.{% ... %}是什么意思? 3.{{ person_name }} 指的是变量么,为什么要用两个 {{}} 呢?

大王饶命 07-11 01:53

用{{}}包围的是变量,如{{person_name}};用{%%}包围的是块标签,如{%if ordered_warranty%}

YeLuo 11-06 06:00

Python3.4 + Django1.7 运行会出错,在过滤器那里会出问题

对这一段的评论会显示在这里

该模板是一段添加了些许变量和模板标签的基础 HTML 。 让我们逐步分析一下:

对这一段的评论会显示在这里

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

wyatt 12-27 04:10

变量中大括号和变量部的空格位,只是编码的一种风格,而不是必须要用空格的吗?

huangz 01-01 00:45

@wyatt 应该是的,你可以试试,去掉空格也不会报错。

57yu 08-18 10:41

test

gru 11-25 09:32

@wyatt 变量必须要被{{}}包含,变量名不能包含空格

1 12-17 07:30

1

对这一段的评论会显示在这里

被大括号和百分号包围的文本(例如 {% 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 %}是可选的。

蝶也愁 08-28 15:35

当存在多重if判断时怎么处理

wk 11-05 03:10

可以遍历迭代器么?

Memory 03-30 06:51

else是可选的意思是可要可不要吧?

对这一段的评论会显示在这里

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

李旭章 12-02 03:16

{{ship_date|date:”F j, Y” }}……指定参数”F j,Y” 前双引号用反了。建议改为: {{ship_date|date:“F j, Y” }}……指定参数“F j,Y”

weetao 01-18 13:22

用反了?英文字符双引号只有一个吧?

行之 12-11 11:14

不应该用中文的引号。 应用英文的。

keroro 08-27 11:48

提示:管道符('|')前后好像不能有空格,有空格会出错。

nicholas 09-24 03:02

filter格式输出

gru 11-25 09:58

unxi的管道是可以有空格的,这里不晓得

田耕 04-06 14:38

F:月份,完整的文本格式,例如 January 或者 March j:月份中的第几天,没有前导零 Y:4 位数字完整表示的年份

安铺靓仔 12-04 07:52

tags和filters看官方文档就好:https://docs.djangoproject.com/en/3.2/ref/templates/builtins/,要适应查看官方文档

对这一段的评论会显示在这里

Django 模板含有很多内置的tags和filters,我们将陆续进行学习. 附录F列出了很多的tags和filters的列表,熟悉这些列表对你来说是个好建议. 你依然可以利用它创建自己的tag和filters。这些我们在第9章会讲到。

Risk 12-12 07:16

看http://www.djangobook.com/en/2.0/index.html,Appendix E: Built-in Template Tags and Filters,应为附录E

Gerrard 07-20 06:59

是f没错,详情可以查看中文的1.0版,去掉网址上的2.0就是了

situs 12-22 13:07

建议尽可能熟悉这些列表内容

Matt 01-28 09:36

http://djangobook.py3k.cn/appendixF/ 各种附录改最后面的一个字母即可

吴某人 04-01 03:32

想知道tags和filter是在哪个文件定义的,可以在定义tags和filter的文件加入自己定义的tags和filter吗?

对这一段的评论会显示在这里

如何使用模板系统

对这一段的评论会显示在这里

让我们深入研究模板系统,你将会明白它是如何工作的。但我们暂不打算将它与先前创建的视图结合在一起,因为我们现在的目的是了解它是如何独立工作的。 。 (换言之, 通常你会将模板和视图一起使用,但是我们只是想突出模板系统是一个Python库,你可以在任何地方使用它,而不仅仅是在Django视图中。)

57 05-04 09:22

"因为我们现在的目的是了解它是如何独立工作的。 。" -> 两个句号?

jawatang 07-20 12:56

楼下你懂的~

zzp 07-31 01:28

好文章

glcust 02-26 15:52

学习

对这一段的评论会显示在这里

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

xiebin 03-08 10:04

很好啊 这个 强大 学习了 3QQQQ

Kyan 04-27 07:13

翻译不太好, 1. Create a Template object by providing the raw template code as a string. 1. 创建一个 Template 对象,将模板代码放入一个 string 中作为参数。

Kyan 04-27 07:19

2. Call the render() method of the Template object with a given set of variables (the context). This returns a fully rendered template as a string, with all of the variables and template tags evaluated according to the context. 2. 调用模板(template)对象的 render() 方法,把一组变量作为上下文(context)传入。这么做将会把模板(template)展开,将所有变量(variables)和标签(tags)都赋予相应的值,并作为 string 返回,

对这一段的评论会显示在这里
  1. 可以用原始的模板代码字符串创建一个 Template 对象, Django同样支持用指定模板文件路径的方式来创建 Template 对象;
  2. 调用模板对象的render方法,并且传入一套变量context。它将返回一个基于模板的展现字符串,模板中的变量和标签会被context值替换。
1 12-17 07:31

1

Asterism2012 06-20 08:50

templates

对这一段的评论会显示在这里

代码如下:

playmud 10-20 10:22

这里需要 python manage.py shell启动,而不是直接 python启动

xiebin 03-08 10:03

很好啊 这个 强大 学习了 3QQQQ

对这一段的评论会显示在这里
>>> 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.
周寿峰 06-10 01:44

ImportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined. 现在按这篇文章的方法来做 方法一: >>> from django.template import Template, Context >>> from django.conf import settings >>> settings.configure() >>> t = Template('My name is {{ my_name }}.') >>> c = Context({'my_name': 'Daryl Spitzer'}) >>> t.render(c) ok通过 方法二: 先确定python的路径 $ which python2.5 /usr/bin/python2.5 $ export PYTHONPATH=/usr/bin/python2.5:~/share $ export DJANGO_SETTINGS_MODULE=test.settings 其中:~/share是django工程test所在的路径 测试一下 >>> from django.template import Template, Context >>> from django.conf import settings >>> t = Template('My name is {{ my_name }}.') >>> c = Context({'my_name': 'Daryl Spitzer'}) >>> t.render(c) ok通过 在Ubuntu中将 export PYTHONPATH=/usr/bin/python2.5:~/share export DJANGO_SETTINGS_MODULE=test.settings 加到~/.profile文件中,每次登录就自动设置了

playmud 10-20 10:20

这里需要 python manage.py shell启动,而不是直接 python启动

白衣骑士 10-24 10:16

python manage.py shell启动 = ipython

wyatt 12-27 04:17

楼上,ipython启动不能正常使用呀。我试过了,照样报错的。还是得用./manage.py shell启动才能正常使用。不过也奇怪,启动后,显示的是ipython的信息。

herock 05-31 16:01

我用python manage.py shell启动后,工作正常

hohooo 08-08 08:57

from django.conf import settings settings.configure()

读解dj 11-20 09:36

用python manage.py shell启动,是怎么启动的

melzg 03-18 14:17

hohooo的方法是对的:增加下面几行。 >>> from django.conf import settings >>> settings.configure()

python-xiyuan 05-10 18:20

楼上方法可行

易枭寒 09-26 06:18

>>>建议写成 In [1]:

pt 12-18 16:27

不可以用ipython,虽然调用了ipython

pt 12-18 16:28

我用python manage.py shell启动后,工作正常

wkshare 01-12 07:55

使用:python manage.py shell 进入后测试template模块就不会出错了。这个评注不能换行。

ForEcho 05-10 16:06

melzg 正确

lincy 08-12 10:44

经测试,在代码头部加上 >>> from django.conf import settings >>> settings.configure() 为可行办法之一(python 2.7;django 1.5)

lincy 08-12 10:49

先python manage.py shell也行,下文有详细解释

Mario 08-27 05:50

这里需要 python manage.py shell启动,而不是直接 python启动 这样就是正常的。并不需要额外的部分

脐橙君 09-23 08:39

除了python manage.py shell这种方式外还可以使用下面的方法: >>> from django.conf import settings >>> settings.configure() >>> from django import template >>> t = template.Template('My name is {{ name }}.') >>> c = template.Context({'name': 'yixiaohan'}) >>> print t.render(c) My name is yixiaohan. >>> c = template.Context({'name': 'xiaowangge'}) >>> print t.render(c) My name is xiaowangge.

脐橙君 09-23 08:40

除了python manage.py shell这种方式外还可以使用下面的方法: (来自http://blog.csdn.net/xiaowanggedege/article/details/8651236) >>> from django.conf import settings >>> settings.configure() >>> from django import template >>> t = template.Template('My name is {{ name }}.') >>> c = template.Context({'name': 'yixiaohan'}) >>> print t.render(c) My name is yixiaohan. >>> c = template.Context({'name': 'xiaowangge'}) >>> print t.render(c) My name is xiaowangge.

Itonla 10-20 07:36

这个评论,真不错,大家在一个平台上交流学习。谢谢上面各位给出的解决方案。

stefan_bo 10-28 07:10

>>> from django.conf import settings >>> settings.configure() >>> t = template.Template('my name is {{ name }}.') Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'template' is not defined >>> from django.template import Template, Context >>> t = template.Template('my name is {{ name }}.') Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'template' is not defined >>> t = Template('my name is {{ name }}.') >>> c = Context({'name': 'Fred'}) >>> print t.render(c) my name is Fred.

Robertyi 11-21 07:16

在代码头部加上 >>> from django.conf import settings >>>settings.configure() 为可行办法(python 3.3;django 1.5),新版本的python还有很多细节变化,print要加上()才能正常使用。 另外一种方法是通过cmd或者shell在manage.py目录下输入命令python manage.py shell来启动shell,蛋疼的是windows下python的shell窗口时在cmd中的……

keetron 01-10 03:46

不知其所以然,哪位给解释一下

NEUSimon 01-17 01:41

不知道怎么从shell启动的童鞋们,下面的详细介绍里有说明如何启动,请叫我雷锋。

vincent 02-25 13:44

>>> from django.conf import settings >>> settings.configure() >>> t = template.Template('my name is {{ name }}.') >>> c = template.Context({'name': 'vincent'}) >>> print(t.render(c)) my name is vincent.

vincent 02-25 13:45

>>> from django.conf import settings<br> >>> settings.configure()<br> >>> t = template.Template('my name is {{ name }}.')<br> >>> c = template.Context({'name': 'vincent'})<br> >>> print(t.render(c))<br> my name is vincent.

bger 02-27 02:10

感谢@vincent

dedyral 04-17 04:29

melzg 正确

匿名读者 06-11 03:58

python manage.py shell可以。

allen 06-26 06:15

ipython启动 没有错误(python2.7,django1.6)

mihello 07-31 14:02

django 1.6.5 测试通过

御坂御坂 08-29 01:57

django 1.6.6 需先python manage.py shell.

IvanKe 09-16 03:30

用 python manage.py shell 可以 另外~~ 加這兩行 from django.conf import settings settings.configure() 也可以。

RobinChan 10-11 13:19

注意这里并不是直接在IDLE下直接运行。看后面,是在命令窗口里运行python mange.py shell后的python环境正常运行。

周明辉 11-14 14:31

注意大小写,在manage.py shell 中代码不用增加是可以的 Python2.7 Django 1.7

chuiwen 01-25 03:43

http://stackoverflow.com/questions/18081369/error-when-using-django-template

羊肉汤 07-15 08:54

>>> from django.conf import settings >>> settings.configure() 亲测Django 1.8 可用。 多谢楼上各位!

cici 09-15 01:13

py2.7+django1.8前奏 python manage.py shell import django django.setup()

吴某人 04-01 03:12

django1.9 Python2.7 ipython 启动失败,错误:</n> bash : ipython: command not find

Kazuhira 06-15 06:44

django 1.9.0 使用python manage.py shell 跟着操作没有问题

jessy 07-20 06:38

我这边执行后提示没有render这个属性哦?。。。

jessy 07-20 08:03

按照1楼说的做后面执行都报这个错了ImportError: No module named settings T.T

jessy 07-20 08:06

额,我又设置好了 ^.^

lol 09-16 07:53

为什么我加入了 from django.conf import settings settings.configure() 还是不行?会报错django.core.exceptions.ImproperlyConfigured: No DjangoTemplates backend is configured.

小市民 11-11 06:36

报错请使用python manage.py shell

对这一段的评论会显示在这里

以下部分逐步的详细介绍

对这一段的评论会显示在这里

创建模板对象

对这一段的评论会显示在这里

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

talent 09-24 03:27

原始模板代码 -> 初始化模板代码

Radon 08-28 09:57

一楼翻的更好

guanbin 09-28 00:46

一楼翻译的很好哎。

kk 05-02 02:38

templete是在base.py 中 为什么不引用‘template.base.Template('My name is {{ name }}.')’

对这一段的评论会显示在这里

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

wyatt 12-27 04:20

./manage.py shell,,在linux中,manage.py是可执行的。

Tomoya 06-07 12:29

但是对于在系统中装有多个python版本的人来说还是用 python manage.py shell比较好,不容易搞混

alex 07-03 10:18

应该是“转到mysite项目目录”而不是“转到project目录”。 见原文: From the mysite project directory created by django-admin.py startproject (as covered in Chapter 2), type python manage.py shell to start the interactive interpreter.

Kuner 09-14 08:46

@wyatt// 而且前面没加 `x' 权限

yuntao 02-17 10:26

嗯,alex 很用心。现在文本里面确实有很多错误,请尽快修正啊。 如果可以开放修改权限的话,我倒是愿意帮忙纠正一些小错误

张斌 01-12 16:38

恩,这快我一开始也不知道为什么要这么启动,但是通过shell直接在python与行,告诉DJANGO——SET——MODUEL没有定义

looly 01-20 05:00

cygwin下无法执行

bravecarrot 08-21 13:48

windows环境下,讲python主程序加到系统path中。然后再manage.py的目录中,按住shift右键,在当前目录打开命令行即可。

Radon 08-29 03:33

startproject创建的目录结构应该是这样的mysite/project/,不知道我理解的是否正确

YeLuo 11-05 07:16

Eclipse下,项目MySite右键 -> Django -> Shell with django environment

对这一段的评论会显示在这里

一个特殊的Python提示符

对这一段的评论会显示在这里

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

1 08-09 12:32

1

jaingm_ 07-04 13:14

试试还起作用不。。。 虽然版本不合适,对我的帮助挺大的,要是这里提交的还起作用,希望能和所有人交流

对这一段的评论会显示在这里

如果你想知道,这里将向你解释它背后是如何工作的。 Django搜索DJANGO_SETTINGS_MODULE环境变量,它被设置在settings.py中。例如,假设mysite在你的Python搜索路径中,那么DJANGO_SETTINGS_MODULE应该被设置为:’mysite.settings’。

stranger 05-31 01:58

当然,也可以直接cd到特定目录的上层目录。不过这种方法不是一劳永逸。

jack 04-27 02:14

可以在开头添加 from django.conf import settings settings.configure()

AIZEN 04-28 12:53

在setting.py这个文件里面没有这个变量啊也。

Scar_l 07-19 09:12

1.4的settings.py里面没有DJANGO_SETTINGS_MODULE?

leejaen 02-22 07:46

@ls,@lss DJANGO_SETTINGS_MODULE='mysite.settings',你们理解错了

huzzar 05-24 03:21

新版本的Django里,DJANGO_SETTINGS_MODULE貌似在manage.py文件中设置os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite_evo.settings")

Kevin 06-03 02:45

本书使用的django版本比较旧,我的1.5版本(>>> import django >>> django.VERSION),不是在这个配置文件里的。

老虎 07-09 02:01

DJANGO_SETTINGS_MODULE是在manage.py里面设置的,本质是一个环境变量,它默认指向应用下的settings.py,也就是mysite.settings,这里翻译有误。

shoumu 08-02 05:46

DJANGO_SETTINGS_MODULE在manage.py中能够找到吧,在setings.py中没有吧

李嘉燊 08-08 08:12

这是manage.py里指定的一个对应,manage.py里的代码是os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

lincy 08-12 10:54

楼上老虎正解,在django 1.5中,DJANGO_SETTINGS_MODULE是在manage.py里面设置的,本质是一个环境变量,它默认指向应用下的settings.py,也就是mysite.settings.(本书所用django版本较老)

prog 02-25 14:16

确实是在manage.py中,多亏了评注啊

cococoding 03-19 14:42

解决方法见 http://javacrazyer.iteye.com/blog/1535323

mihello 07-31 14:27

我是中英对照着看 http://www.djangobook.com/en/2.0/chapter04.html

匿名读者 06-13 14:28

加了settings.configure()后报No DjangoTemplates backend is configured.的错。怎么办啊

chg_self 07-15 01:21

DJANGO_SETTINGS_MODULE是在manage.py中

对这一段的评论会显示在这里

当你运行命令:python manage.py shell,它将自动帮你处理DJANGO_SETTINGS_MODULE。 在当前的这些示例中,我们鼓励你使用python manage.py shell这个方法,这样可以免去你大费周章地去配置那些你不熟悉的环境变量。

对这一段的评论会显示在这里

随着你越来越熟悉Django,你可能会偏向于废弃使用manage.py shell ,而是在你的配置文件.bash_profile中手动添加 DJANGO_SETTINGS_MODULE这个环境变量。

深圳远程教育 11-10 08:14

如何手动设置,求解???

sevear 02-16 05:15

回楼上,不是都说了修改.bash_profile文件,添加 DJANGO_SETTINGS_MODULE="你的setting文件路径”

athos 03-07 03:50

假设你的路径是这样的: /home/athos/django/mysite/manage.py 则在/home/athos/.bash_profile 增加两行: export PYTHONPATH=$PYTHONPATH:/home/athos/django/mysite/ export DJANGO_SETTINGS_MODULE=mysite.settings 重新登录即生效

徐余吉 12-13 15:19

添加以下代码: from django.conf import settings settings.configure() 应该也有效果

anon 01-23 02:48

windows下的.bash_profile在哪里呀 求解释啊

李先森 02-24 12:45

回楼上 google windows设置环境变量

cococoding 03-19 14:43

解决方法见 http://javacrazyer.iteye.com/blog/1535323

匿名读者 06-11 04:31

.bash_profile在那里啊,只有.profile

吴某人 03-31 10:31

我的树莓派的隐藏文件夹并没有.bash那个文件夹

对这一段的评论会显示在这里

让我们来了解一些模板系统的基本知识:

对这一段的评论会显示在这里
>>> from django.template import Template
>>> t = Template('My name is {{ name }}.')
>>> print t
iComes 12-16 09:04

第二行应该是template.Template...

wyatt 12-27 04:24

这一行没错,因为直接导入了Template,注意第一行,和上面的例子是有区别的。

pyplus 10-13 01:54

我想在ipython下测试结果发现提示那个setting模块变量未设置。因为我的ipython不是安装的而是直接运行,如何解决啊?如果setup ipython就没事了,我不想将ipython安装进python的package里

hulupiao 09-26 06:20

#python3.7&django2.1 print(t)

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里
<django.template.Template object at 0xb7d5f24c>
vincent 02-25 14:01

<django.template.base.Template object at 0x01E2FCD0>

对这一段的评论会显示在这里

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

YueZheng 11-15 01:45

在别的资料中介绍 0xb7.... 有对象在内存中地址的说法。现在混乱了,到底是什么???

JeryRen 11-15 10:29

感觉0xb7d5f24c应该指的是t变量的地址,即当前模版对象的地址。

mrwang1992 01-15 13:13

恢复楼上的 就我一个新手看 这个应该就是类似于C指针类的东西 指向此模版 内存当中的位置

dilidilidi 04-09 09:32

翻了原版英文的,是object id

keetron 01-10 04:17

应该是内存位置吧,他的是32位,我的是64位

Django1.6 04-06 14:25

这个ID对应的就是内存地址

mil 10-30 15:15

对象的ID就是该对象在内存的地址。用地址做对象ID是很好的,因为对象一旦存在就一定在内存中。

Alfred 10-11 02:35

这里应该是内存地址而不是ID

对这一段的评论会显示在这里

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

mark 06-27 15:31

对这一段的评论会显示在这里
>>> 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'
Jack 04-06 15:08

这个例子为什么会异常,为什么会是无效的tags?

Jack 04-06 15:27

抱歉,没仔细看,这里的错误应该是{% notatag %} 这并非是一个标签的格式。

牛三金 04-21 16:07

应该是: t = Template('{{ notatag }}')

袁龙 01-16 12:46

都这么憨啊,上面说了模板标签是这样的{% if xxx%} {% else xxx%} 这里的{% notatag %}不是django里定义的模板标签类型,所以报错了,就 跟关键字一样么,没有定义这个关键字。

noatag 02-04 06:35

noatag===>not a tag

对这一段的评论会显示在这里

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

小菜 12-28 09:22

谁能解释一下块标签与模板标签是同义的什么意思

qianlifu 01-12 16:29

我觉得系统错误这部分需要把中英文对照写出来。因为系统错误提示字段是英文的

jamzhou 02-27 03:16

这块应该把对应的英文Error写出来会更好

对这一段的评论会显示在这里

系统会在下面的情形抛出 TemplateSyntaxError 异常:

对这一段的评论会显示在这里
  • 无效的tags
  • 标签的参数无效
  • 无效的过滤器
  • 过滤器的参数无效
  • 无效的模板语法
  • 未封闭的块标签 (针对需要封闭的块标签)
对这一段的评论会显示在这里

模板渲染

keroro 08-27 11:19

“集合” --> “字典”

来了 07-28 06:29

111

对这一段的评论会显示在这里

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

erhuabushuo 05-14 02:23

和它们值的集合-》和它们关联的值。

nicholas 09-24 03:08

用context为模板传值

Yo 01-16 02:59

context --〉Context

对这一段的评论会显示在这里

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

庞铮 04-21 07:52

它的构造函数

一只梨 12-03 08:59

“模板渲染”应该叫“渲染模板”。模板好像一块被设置好的画布,Context好比颜料。主宾关系要分清,否则容易误会。

NEUSimon 01-17 02:05

当你拥有Template对象时,你可以通过给他一个context 来向他传递数据,一个context只是一系列模板变量的名字和相关的值, template用这种方法去填充变量,评价标签。

starof 02-04 06:42

同意@一只梨

对这一段的评论会显示在这里
>>> from django.template import Context, Template
>>> t = Template('My name is {{ name }}.')
>>> c = Context({'name': 'Stephane'})
>>> t.render(c)
u'My name is Stephane.'
ilrxx 11-21 07:43

为什么context的参数是中文的话,t.render(c),无法显示中文呢?只会显示u'my name is'

qq345421243 05-08 07:08

print t.render(c)会显示中文

Youthlin Chen 05-23 15:47

中文也会又反应,\u9700 (Unicode编码吧?)这样 print t.render(c)就能显示汉字

xinwan818 03-31 02:27

可以理解成Template 定义了所有的键 通过Context为相应的键填充值

对这一段的评论会显示在这里

我们必须指出的一点是,t.render(c)返回的值是一个Unicode对象,不是普通的Python字符串。 你可以通过字符串前的u来区分。 在框架中,Django会一直使用Unicode对象而不是普通的字符串。 如果你明白这样做给你带来了多大便利的话,尽可能地感激Django在幕后有条不紊地为你所做这这么多工作吧。 如果不明白你从中获益了什么,别担心。你只需要知道Django对Unicode的支持,将让你的应用程序轻松地处理各式各样的字符集,而不仅仅是基本的A-Z英文字符。

宾森 09-13 15:57

第三行: 所做这这么多工作吧→所做的这么多工作吧

易枭寒 09-26 06:32

如果不明白你从中获益了什么 获益-->收获?

sevear 02-16 05:17

一直很吐血python2.x不内置支持unicode字符串,天啊

ivy 04-16 08:32

上面错误提示:NameError: name 'Context' is not defined

ivy 04-16 08:32

了解了,忘记导入了!

July 02-20 13:08

Python3 的话t.render(c)就直接是字符串了,没有u,因为内建的都是u

sytu 03-05 03:14

python3 中的所有字符串都是Unicode编码的字符序列, 与django的模板中的字符串类型一致. 这里作者指的是与 以UTF-8或者CP-1252编码的普通Python2字符串 不同

对这一段的评论会显示在这里

字典和Contexts

庞铮 04-21 08:00

字典和Context

Yo 01-16 12:02

在原书中是:Dictionaries and Contexts。我想它是指多个吧

卡卡 01-02 03:03

字典和Context很类似

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里

变量名必须由英文字符开始 (A-Z或a-z)并可以包含数字字符、下划线和小数点。 (小数点在这里有特别的用途,稍后我们会讲到)变量是大小写敏感的。

易枭寒 09-26 06:36

小数点--> 英文句点?

tunzao 05-24 06:37

下划线开始不行吗?

hex2bin 03-13 12:07

@tunzao 不可以用下划线开头

对这一段的评论会显示在这里

下面是编写模板并渲染的示例:

对这一段的评论会显示在这里
>>> from django.template import Template, Context
>>> raw_template = """<p>Dear {{ person_name }},</p>
...
... <p>Thanks for placing an order from {{ company }}. It's scheduled to
... ship on {{ ship_date|date:"F j, Y" }}.</p>
...
... {% 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 %}
...
... <p>Sincerely,<br />{{ company }}</p>"""
>>> t = Template(raw_template)
>>> import datetime
>>> c = Context({'person_name': 'John Smith',
...     'company': 'Outdoor Equipment',
...     'ship_date': datetime.date(2009, 4, 2),
...     'ordered_warranty': False})
>>> t.render(c)
u"<p>Dear John Smith,</p>\n\n<p>Thanks for placing an order from Outdoor
Equipment. It's scheduled to\nship on April 2, 2009.</p>\n\n\n<p>You
didn't order a warranty, so you're on your own when\nthe products
inevitably stop working.</p>\n\n\n<p>Sincerely,<br />Outdoor Equipment
</p>"
Jasper 02-06 06:07

导入模板前,先导入设置 >>>from django.conf import settings >>> settings.configure()

dowson 03-18 14:51

在这里注意ship_date|date之间的管道符,如果中间有空格,会抛出异常

abc 04-12 03:50

如果是通过manage.py shell运行的就可直接按例子运行,就不用导入from django.conf import settings

ivy 04-17 00:38

abc +1

ont 10-25 05:42

在cmd中,如果不小心代码写错,并且已经按下回车,怎么更改?

波哥 11-19 06:59

这里的管道传递是如何传递的?没看太明白,另外,后面3个参数可以从哪里得到?代表什么意思?

cjyfff 01-12 15:54

同ls,我也不懂datetime.date(2009, 4, 2)的意义

加菲猫 02-08 03:53

关于过滤器-时间: 可以参考下面的连接 http://blog.csdn.net/xyp84/article/details/7945094

Jack 04-06 16:53

ls的链接还没讲完整,再看一下这个就完整了http://www.54chen.com/p/function.date.html

hukefan 07-23 02:07

raw_template =""" 为何这里有三个双引号??

mihello 07-31 15:50

@hukefan """ 和 ''' 三引号是输入多行文本用,请自行百度

YeLuo 11-06 06:58

Python3.4 + Django1.7 在{{ ship_date|date:"F j, Y" }}处一直有问题,求解?

lambert 01-02 03:09

为什么返回的结果是 You didn't order a warranty, so you're on your own when\nthe products inevitably stop workin,而不是Your warranty information will be included in the packaging.我不太明白 {% if ordered_warranty %}的意思.

对这一段的评论会显示在这里

让我们逐步来分析下这段代码:

对这一段的评论会显示在这里

首先我们导入 (import)类 TemplateContext ,它们都在模块 django.template 里。

对这一段的评论会显示在这里

我们把模板原始文本保存到变量 raw_template 。注意到我们使用了三个引号来 标识这些文本,因为这样可以包含多行。

lz 06-15 08:05

三个引号可以包含多行

雪雪 10-15 06:15

三个引号什么作用?还是不太理解

lxy 11-05 06:17

看到三个引号下方开头有三个...的句子了吗,这就是包含多行

Ignora 01-23 08:22

三引号的作用和Markdown中的类似,Python中三单引号和三双引号作用一致

对这一段的评论会显示在这里

接下来,我们创建了一个模板对象 t ,把 raw_template 作为 Template 类构造函数的参数。

我是楼主 07-28 06:37

111

对这一段的评论会显示在这里

我们从Python的标准库导入 datetime 模块,以后我们将会使用它。

对这一段的评论会显示在这里

然后,我们创建一个 Context 对象, cContext 构造的参数是Python 字典数据类型。 在这里,我们指定参数 person_name 的值是 'John Smith' , 参数company 的值为 ‘Outdoor Equipment’ ,等等。

C.J. 06-14 06:16

c.Context中的"点"错误的运用了中文字符

janvy 10-27 05:33

那就是个句号,一个Context对象c。 Context构造函数的参数是.....

manu 11-16 02:54

contex字典中的值,能够在template中被直接访问

C.F. 01-08 13:09

文章当中的是正确的。创建了一个对象c,这句就结束了。没有c.Context这种用法。

ode2free 04-07 16:19

ordered_warranty 的值为False. 所以显示 {% else %} 的内容。

linuxtro 05-05 04:15

ordered_warranty 的值是在哪里设置的啊?

jastme 10-22 13:36

ordered_warranty 是个布尔值,在字典中设置成了False

对这一段的评论会显示在这里

最后,我们在模板对象上调用 render() 方法,传递 context参数给它。 这是返回渲染后的模板的方法,它会替换模板变量为真实的值和执行块标签。

对这一段的评论会显示在这里

注意,warranty paragraph显示是因为 ordered_warranty 的值为 True . 注意时间的显示, April 2, 2009 , 它是按 'F j, Y' 格式显示的。

ibrahi7438 05-06 08:14

设置的是False吧

peter 10-22 23:28

False

小孩民 03-16 04:42

<p> </p>是什么意思??

不满 06-20 09:40

<p>是html标签

匿名读者 12-04 03:21

F j, Y 是什么格式呢

凳子 03-29 07:51

F,j,y应该是模板过滤器

Ignora 01-23 08:31

F j, Y 的左右在之前filter一段中有个评注具体解释过

对这一段的评论会显示在这里

如果你是Python初学者,你可能在想为什么输出里有回车换行的字符('\n' )而不是 显示回车换行? 因为这是Python交互解释器的缘故: 调用 t.render(c) 返回字符串, 解释器缺省显示这些字符串的 真实内容呈现 ,而不是打印这个变量的值。 要显示换行而不是 '\n' ,使用 print 语句: print t.render(c)

对这一段的评论会显示在这里

这就是使用Django模板系统的基本规则: 写模板,创建 Template 对象,创建 Context , 调用 render() 方法。

对这一段的评论会显示在这里

同一模板,多个上下文

对这一段的评论会显示在这里

一旦有了 模板 对象,你就可以通过它渲染多个context, 例如:

一只梨 12-03 09:28

Context是主语,“渲染”是动词,“模板”是宾语。 建议译为: 一旦有了模板对象,它可以被多个Context对象渲染。

oscar 02-01 12:45

建议这个标题的context不用翻译,毕竟是个特有名词。

一只梨 02-16 02:29

建议改为“一旦有了模板对象,你就 可以用多个Context来渲染它。”

Kevin 04-11 10:03

建议这个标题的context不用翻译,毕竟是个特有名词。

ming 07-11 08:20

ls各位都说的很好

atlas 09-27 05:06

@一只梨 +1

DK 10-21 02:07

一直覺得,把 "渲染" 改成 "代入" 會比較通順?

对这一段的评论会显示在这里
>>> from django.template import Template, Context
>>> t = Template('Hello, {{ name }}')
>>> print t.render(Context({'name': 'John'}))
Hello, John
>>> print t.render(Context({'name': 'Julie'}))
Hello, Julie
>>> print t.render(Context({'name': 'Pat'}))
Hello, Pat
对这一段的评论会显示在这里

无论何时我们都可以像这样使用同一模板源渲染多个context,只进行 一次模板创建然后多次调用render()方法渲染会更为高效:

donly 03-06 04:06

是用context来渲染template。t.render(c)

donly 03-06 11:16

@donly Sorry, 模板引擎渲染上下文(context)数据

对这一段的评论会显示在这里
# Bad
for name in ('John', 'Julie', 'Pat'):
    t = Template('Hello, {{ name }}')
    print t.render(Context({'name': name}))

# Good
t = Template('Hello, {{ name }}')
for name in ('John', 'Julie', 'Pat'):
    print t.render(Context({'name': name}))
匿名读者 04-10 03:21

为什么?

Sonic 06-25 10:24

Sonic 06-25 10:24

我也不知道!

yuanjia 07-03 08:48

bad里面t = Template('Hello,{{name}}')会执行多次,而good里面只执行一次

Sonic 07-05 02:59

Bad的一段不会引发错误。 但是定义模板在循环体内循环多次,的确不合适。

whk 03-27 07:33

template的初衷就是以最少成本进行重复劳动,故template有点基类的赶脚

lincy 08-12 11:18

楼上yuanjia说得很好,重复创建模板是低效的

adai 08-13 08:27

三千君 10-03 14:07

原因就是编程思想,不要重复劳动,

匿名读者 04-03 09:30

有点类似数据库的概念,先创建表,然后根据需要灌数据就行了

周波 06-13 10:22

译者辛苦了,好人一生平安

Radon 08-29 06:46

重复创建模板是低效的,所以是bad

RobinChan 10-12 03:01

其实也是一些代码的原则,能不重复执行的代码都写在循环的外面,提高代码的速度。

fellow 05-30 14:53

这里应该是因为创建模板的开销应该比较大吧

sytu 03-05 03:41

你是愿意每次喝水都重新再买个杯子还是买个杯子以后每次喝水都用它?

对这一段的评论会显示在这里

Django 模板解析非常快捷。 大部分的解析工作都是在后台通过对简短正则表达式一次性调用来完成。 这和基于 XML 的模板引擎形成鲜明对比,那些引擎承担了 XML 解析器的开销,且往往比 Django 模板渲染引擎要慢上几个数量级。

基于正则比基于xml快几个数量级吗? 09-10 00:47

Xvaier 07-14 14:26

简直威武

urmyfaith 09-13 07:07

每次都要登录? 评论可以登录就好了...

匿名读者 12-24 01:38

我为啥不用登录?

匿名读者 01-09 01:36

test

xxx 01-09 01:36

test

匿名读者 03-03 06:07

0010

匿名读者 04-25 18:42

haha

匿名读者 07-04 04:36

dsds

祝长松 09-16 08:37

test

匿名读者 12-16 09:54

可以不用登陆吗

sss 03-29 08:15

sas

匿名读者 04-14 11:45

可以呀

匿名读者 11-02 07:49

1

深海孙一峰 05-24 22:04

干死黄旭东~

匿名读者 12-18 07:14

蟑螂能对空

匿名读者 05-17 01:03

不需要吧

匿名读者 08-15 04:30

哈哈哈

泥奏凯 10-23 09:22

尽量少写模板,写起来是挺烦的

匿名读者 07-19 09:05

test123

对这一段的评论会显示在这里

深度变量的查找

Xi Guan 03-19 19:53

Context Variable 查找要比什么深度变量查找容易理解的多

匿名读者 11-02 07:49

1

对这一段的评论会显示在这里

在到目前为止的例子中,我们通过 context 传递的简单参数值主要是字符串,还有一个 datetime.date 范例。 然而,模板系统能够非常简洁地处理更加复杂的数据结构,例如list、dictionary和自定义的对象。

对这一段的评论会显示在这里

在 Django 模板中遍历复杂数据结构的关键是句点字符 (.)。

c 10-11 07:00

(. )( .) 請允許我邪惡一下

=_= 07-04 04:59

=_+

对这一段的评论会显示在这里

最好是用几个例子来说明一下。 比如,假设你要向模板传递一个 Python 字典。 要通过字典键访问该字典的值,可使用一个句点:

对这一段的评论会显示在这里
>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
u'Sally is 43 years old.'
mdemo 10-27 00:33

import Template的Template是不是小写 windows下大写错误 另外提示 找不到Context

zj 10-30 12:43

t是小写 不需要加后面的context

donly 03-06 04:12

@zj Context需要加

kevinkelin 02-20 10:01

t = Template('{{ person.name }} is {{ person.age }} years old.') 这里的person 要和下面的c = Context({'person': person})对应,如上面改成了persons123.name,则下面context的时候也要写成{'persons123':person}

wff0316 04-25 12:03

楼顶 你看看前面的设置就知道在哪里设置Context了 >>> from django.template import Template, Context >>> from django.conf import settings >>> settings.configure() >>> t = Template('My name is {{ my_name }}.') >>> c = Context({'my_name': 'Daryl Spitzer'}) >>> t.render(c) ok通过

JC 08-14 03:27

person = {'name':'Jesse', 'age':'30'} t = Template('{{ Person.name}} is {{person.age}} years old.') c = Context({'Person': person}) print t.render(c) 打印出来是Jesse is years old.。少了年龄

carl 09-17 14:50

楼上,你打印出来少了年龄,是因为你在初始化Template时年龄用的是‘person.age’,正确的应该是‘Person.age’。从Context传入的变量名为‘Person’,Django大小写是敏感的。(主要是这个栗子容易造成误解)

sherlock 07-01 02:31

这里单纯的字典person,如果执行person.name会报错。但是在模版里面却可以用,这是因为django自成一套吗?

mouday 11-30 02:36

讲得很好呀,清楚明白

对这一段的评论会显示在这里

同样,也可以通过句点来访问对象的属性。 比方说, Python 的 datetime.date 对象有 yearmonthday 几个属性,你同样可以在模板中使用句点来访问这些属性:

对这一段的评论会显示在这里
>>> from django.template import Template, Context
>>> import datetime
>>> d = datetime.date(1993, 5, 2)
>>> d.year
1993
>>> d.month
5
>>> d.day
2
>>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.')
>>> c = Context({'date': d})
>>> t.render(c)
u'The month is 5 and the year is 1993.'
evilloop 08-25 09:56

感觉 其实 django只是提供了一个python脚本和html网页的接口,可以让html网页里使用python里的变量

ls 12-02 02:11

同楼上,我也是这么觉得

pyer 04-22 07:29

这段代码在py 2.7.9 + django 1.8下会出错。时间那部分有问题

fellow 05-30 14:58

@pyer,python 2.7.3+Django 1.8.2运行无问题

匿名读者 10-19 07:59

这个不是django的特性 这是python本身特性

对这一段的评论会显示在这里

这个例子使用了一个自定义的类,演示了通过实例变量加一点(dots)来访问它的属性,这个方法适用于任意的对象。

Frank 08-20 11:37

我没有学过Python,在自定义函数那块遇到了一点点问题,已经解决了,注意def前面有空格,还有就是__init__(init前和后各有两个下滑线)

donly 03-06 04:32

@Frank 那是缩进,Python语法特色

浮云比翼 06-10 02:51

这里的{{ person.first_name }} {{ person.last_name }}里的person的P是不是应该大写?

Scar_l 07-19 11:34

c = Context({'person': Person('John', 'Smith')}) 后面的p不用大写吧

follow 07-20 08:26

Person是类名,peson是类的实例。所以第二个需要大写

follow 07-20 08:27

Person是类名,peson是类的实例。所以第二个需要大写 @Scar_l

louis 09-19 03:36

self 是不是类似形参的形参?传递值(的算法)? 下面这行的代码是为了指出后面p.first_name 和p.last_name的计算方法?即分别对应Person('Jhon',Smith')的参数值? ------self.first_name, self.last_name = first_name, last_name

深圳远程教育 11-10 08:43

person不是实例,只是一个键,值对应的是类,也不是实例....

zlleah 12-18 09:54

@深圳远程教育 实例化Python类的方法不就是调用这个类的方法吗? @浮云比翼 vs @Scar_l Template的person对应Context中的键,而Context中的person仅仅是个键,换成其它任意一个变量参数都可以,Context值中的Person则是实例化自定义的Person这个类

cabbageKK 05-16 17:24

第四行输入完之后按回车键出现的还是...,怎样才能让它出现>>>呢?

笑歌 06-07 15:38

{‘person’:Person(‘John’,‘Smith’)}这是传给Context一个字典,第一个person是键,后面是一个类型为类的值,这个类是 Person,这样理解应该没错吧

fiy fish 07-23 15:15

@cabbageKK 再回车下就行

lincy 08-12 11:29

@笑歌,Person(‘John’,‘Smith’)是在实例化Person这个类,括号内的是参数

Leon 09-12 03:00

我在t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.') 这行提示我t 是 invalid syntax 有人知道怎么办吗

Ryan 10-05 23:23

你应该是在...后面写的代码,再回车下变成>>>提示符就不会了@Leon

jimmy 11-07 03:54

self.first_name, self.last_name = first_name, last_name 这一行后面需要再敲回车,记住一定要有,我的是python2.6.6

波哥 11-19 07:40

这里的person只是字典里的键,和类没关系,最后渲染的时候调用Person类,因为self的原因所以直接调用了,大家可以试试把person改成其他的名字,都是可以的,但是要上下呼应

starof 03-19 03:22

@波哥说的对

vension 03-23 06:05

这地方真不会

飞哥 05-01 11:15

把在三条改一下,应该能懂了: >>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.') >>> c = Context({'person': Person('John', 'Smith')}) >>> t.render(c) 更改如下: >>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.') >>> tempc = Person('John', 'Smith') >>> c = Context({'person': tempc}) >>> t.render(c)

mr.liu 05-22 02:01

不会就去看下python面向对象的讲解吧,类的属性,类函数等等

plom 10-05 05:47

可以将Context({'person':Person('John','Smith')})理解为: person=Person('John','Smith'),这样person就是Person类的一个实例,然后通过Template函数调用person.first_name,last_name,其实Context里的参数‘person’键对应的值就是一个类,只不过我们原先看到的是字典或者字符窜比较容易理解,但是字典和字符窜也是类,只不过可以直接赋值,在python中,是可以继承dict,list,tuple的,因为这些都是类

匿名读者 11-20 07:50

>>> class Person(): ... def __init__(self,name,age): ... self.name = name ... self.age = age ... >>> p = Person("gang",17) >>> p <Person object at 0x0000000004C7E9B0> >>> p.name 'gang' >>> p.age 17 >>> t = Template("i am {{p.name}}, age is {{p.age}}") >>> c = Context({"p":p}) >>> t.render(c) 'i am gang, age is 17'

吴某人 04-01 05:18

为什么c = Context里面只有两个参数

吴某人 04-01 05:40

为什么定义的函数必须是__init__?不是说函数名不影响作用的吗?返回的错误是 File "<console>", line 1,in <module> /n TypeError: object() takes no parameters

sytu 03-05 03:48

python类方法必须增加一个额外的形参,而且它 必须处于第一个形参的位置, 但是在调用类方法时不要也不必为这个额外的形参传值, python 会自动代劳。这个特别的变量引用对象本身,按照惯例它被命名为 self。 也就是C++中的this指针, 指向调用该类方法的对象

对这一段的评论会显示在这里
>>> from django.template import Template, Context
>>> class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name, self.last_name = first_name, last_name
>>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
>>> c = Context({'person': Person('John', 'Smith')})
>>> t.render(c)
u'Hello, John Smith.'
匿名读者 11-15 03:22

mark

苏艾丰 11-29 17:52

干嘛创建Person类后面有个(object)?没有也可以啊

wangtao 01-01 12:40

@楼上,这是python中新式类和老式类的区别,你可以找找资料

落樱神斧 06-07 01:42

这里object可以当做javascript里的object理解,无非就是个大字典嘛!

mihello 08-01 03:57

python3 默认就是新式类了,python要用新式类就得带上object这个参数。 新式类 在多重继承的时候是广度优先遍历,老式类是深度优先,其他请自行百度。。。

mihello 08-01 03:58

python3 默认就是新式类了,python2要用新式类就得带上object这个参数。 新式类 在多重继承的时候是广度优先遍历,老式类是深度优先,其他请自行百度。。。

mayne 06-20 17:44

在pycharm4.5.2的python console中输入这段代码,到t = Template('Hello, {{person.first_name}} {{person.last_name}}.')这句后弹出‘ImproperlyConfigured: Requested setting TEMPLATES, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings. ’不解

plom 10-05 05:29

@mayne这种情况我也遇到过,我的情况是没有进入到python manage.py shell中

kunnka wong 05-25 06:51

楼上的楼上,上文有提到,不使用python manage.py shell需要自行配置环境变量

sytu 03-05 05:09

python3中的类已经隐式继承了object,所以,python3中写不写继承object都是没有区别的

对这一段的评论会显示在这里

点语法也可以用来引用对象的 方法。 例如,每个 Python 字符串都有 upper()isdigit() 方法,你在模板中可以使用同样的句点语法来调用它们:

对这一段的评论会显示在这里
>>> from django.template import Template, Context
>>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
u'hello -- HELLO -- False'
>>> t.render(Context({'var': '123'}))
u'123 -- 123 -- True'
0000 07-04 08:25

对这一段的评论会显示在这里

注意这里调用方法时并 没有 使用圆括号 而且也无法给该方法传递参数;你只能调用不需参数的方法。 (我们将在本章稍后部分解释该设计观。)

TankyWoo 04-26 06:49

这里要注意!

dogxxgod 05-06 03:17

only for functions without var

笑歌 06-07 15:44

为什么不能调用带括号的方法??

zhanhe 08-31 03:40

字符串的方法upper和isdigit没有括号,要注意!

cococoding 03-19 14:49

注:方法没有括号,更不可能带参数

落樱神斧 06-07 01:47

django的设计者在这里搞这么一出是想坑多少人???

匿名读者 06-10 07:49

函数不能有参数,这么设计有他的道理

cbxjj 06-26 07:42

坑爹啊这是

cbxjj 06-26 07:45

坑爹啊这是 带括号还报错 太灵活了 为什么却不去适应带括号的情况

django 11-26 04:00

要传参数,请参考后面高级模板章节,django有它自己的模板语法

tiy 04-09 12:05

!!!方法不能加括号~

Tiy 04-09 12:10

!!!方法不能加括号~

camellhf 01-31 12:59

mark~

Neinaa 04-16 08:47

天哪~自己一套……

Neo 05-01 07:44

都别BB了,既然想用django就得接受他的方式,毕竟人家站的高度和咱们不是一个层次,这么设计肯定有原因,只是我们还没遇到。

匿名读者 07-17 14:04

mark

匿名读者 10-25 09:02

方法不能加括号,所以不能使用带参数的方法

xc 10-25 09:02

方法不能加括号,所以不能使用带参数的方法

对这一段的评论会显示在这里

最后,句点也可用于访问列表索引,例如:

匿名读者 07-15 14:05

ggg

对这一段的评论会显示在这里
>>> from django.template import Template, Context
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
u'Item 2 is carrots.'
mil 10-30 16:08

这个挺吊

耿雷明 06-24 10:25

item.2可以直接获取第二项,学到了

Ignora 01-24 01:05

item.2是第三项

对这一段的评论会显示在这里

不允许使用负数列表索引。 像 {{ items.-1 }} 这样的模板变量将会引发TemplateSyntaxError

TankyWoo 04-26 06:51

这里要注意!

Snapshot 10-31 15:00

关于 {{ person.name.upper }}是否调用upper 方法还要看person 字典本身的内容, 比如person如下: person = {'name': {'upper': 'haha'}, 'age': '43'} 那么就不是调用upper方法 而是 person['name']['upper']

qq345421243 05-08 08:31

经测试,楼上正解

Lynn 10-06 06:31

什么正解啊,这根本就不是一回事。建议看看下面话,“当模板系统在变量名中遇到点时,按照以下顺序尝试进行查找:”还有这句“句点查找可以多级深度嵌套。”这里之所以不是当作upper函数是因为“句点查找可以多级深度嵌套。”这句话,因为.查找是有顺序的,先找字典类型再查找方法,你这里仅仅是因为恰巧用了一个跟upper函数同名的字典属性而已,当然得按照顺序把字典属性扒完了再继续看方法了,LS两位这种取巧的自以为是谁都能看出来,别再误解后人好不好啊?

cbxjj 06-26 07:50

2L不也是这么理解的 4L别激动 先查找字典 再属性再方法

mihello 08-01 12:23

2楼的在django语法逻辑上是没错,但开发的是不会这么命名,这样徒添麻烦。

aaron 05-04 03:35

真理越辩越明,通过大家的讨论对这一部分认识更深刻就好了,重在学习

Ignora 01-24 01:09

不是“经测试”就一定是正解

对这一段的评论会显示在这里

Python 列表类型

对这一段的评论会显示在这里

一点提示: Python的列表是从0开始索引。 第一项的索引是0,第二项的是1,依此类推。

对这一段的评论会显示在这里

句点查找规则可概括为: 当模板系统在变量名中遇到点时,按照以下顺序尝试进行查找:

对这一段的评论会显示在这里
  • 字典类型查找 (比如 foo["bar"] )
  • 属性查找 (比如 foo.bar )
  • 方法调用 (比如 foo.bar() )
  • 列表类型索引查找 (比如 foo[bar] )
Ryan 10-05 23:30

这点很重要啊,句点的查找顺序

ls 12-02 02:19

这个地方感觉有机可乘

terry 03-06 09:09

首先字典类型查找,最后是列表索引类型查找,咋感觉这两点没区别啊

terry 03-06 09:20

列表类型索引查找 (比如 foo[bar] ),应为doo.2.打错了啊

电饭锅 02-04 10:40

重要调用顺序

对这一段的评论会显示在这里

系统使用找到的第一个有效类型。 这是一种短路逻辑。

对这一段的评论会显示在这里

句点查找可以多级深度嵌套。 例如在下面这个例子中 {{person.name.upper}} 会转换成字典类型查找( person['name'] ) 然后是方法调用( upper() ):

对这一段的评论会显示在这里
>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name.upper }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
u'SALLY is 43 years old.'
jason 12-20 08:40

这个变量为什么写成‘person':person.这部分怎么和前面的字典对应的

zhanhe 08-31 03:52

@jason, Context({'person':person})第一个person表示模板变量,第二个person是变量值,而变量值是一个字典。

nicholas 09-24 03:20

upper没加(),很不习惯

匿名读者 03-29 14:33

context({person:person}),前一个变量换成其它名称更利于理解,例如temp,同样上面person.name.upper等的person也要换了

weller 09-24 09:04

>>> persons = {'name':'Tom','age':28} >>> t = Template('{{person.name.upper}} is {{person.age}} years old.') >>> t.render(Context({'person':persons})) u'TOM is 28 years old.' >>> person多个s就更清楚了。

对这一段的评论会显示在这里

方法调用比其他类型的查找略为复杂一点。 以下是一些注意事项:

mark 06-28 15:06

lixuequa 09-17 08:16

略微复杂一点

戚辅光 01-08 14:56

Mark

donghui 10-10 13:25

nice

对这一段的评论会显示在这里

在方法查找过程中,如果某方法抛出一个异常,除非该异常有一个 silent_variable_failure 属性并且值为 True ,否则的话它将被传播。如果异常被传播,模板里的指定变量会被置为空字符串,比如:

Chika 03-18 07:39

“如果异常有silent_variable_failure属性,则模板里的指定变量会被置为空字符串”

objectjava 05-25 07:36

同上

匿名读者 07-12 10:02

同上,作者写反了

fool 10-23 02:51

传播可译为引发或者抛出 如果异常被传播应改为如果异常被处理,原文If the exception does have a silent_variable_failure attribute, the variable will render as an empty string

louis 09-19 05:59

我敲第三行:def first_name(self): 然后回车,提示出错,指向def中的f,提示IndentationError:expected an indented block 什么情况?我也木有学过python.......

keyman 10-24 04:00

@louis 你的那个错误是因为 你没有缩进

呆滞的慢板 01-27 16:43

作者写反了!!改过来吧!!

sinoyster 07-04 01:46

“如果异常有silent_variable_failure属性,则模板里的指定变量会被置为空字符串”

wngn 08-28 08:13

不看下评注,都不明白作者写的是啥!!

匿名读者 10-16 02:44

感谢评注的各位

请教大家 10-16 02:48

没有评注真是看不懂

吴某人 04-01 06:38

作者没写错,也没写反。属性不为真的话,异常传播(使用异常值往下处理),而这个异常会使得指定变量变为空字符串。属性为真,则异常不传播,表现为方法没有被调用,方法不会对变量产生影响。下面的例子就表现在不会对account进行delete方法。大家仔细读一读,感受一下“除非”“否则”这两个词。django模板的方法是不允许调用变量的。

kunnka wong 05-25 07:27

PersonClass4这个类里的方法抛出了silent_variable_failure = True,最后变量被置空了,说明异常是被传播了还是没被传播?

YANG WANG 08-25 05:44

@kunnka wong that means exception won't be propagated

匿名读者 01-11 08:32

标记

匿名读者 08-03 07:02

mark

test 03-04 07:55

在方法查找过程中,如果某方法抛出一个异常,除非该异常有一个 silent_variable_failure 属性并且值为 True ,否则的话它将被传播。如果该异常 确有 属性 silent_variable_failure ,那么(所查找)变量将被渲染为空字符串, 这个是1.0的注释,可以对应着看看。

俊山 12-23 15:31

这里应该是“如果异常不被传播,程序执行不报错中断,模板里指定变量的部分被置为空字符串”。silent_variable_failure=True 可以理解为对异常保持“沉默”,即不上传异常。

对这一段的评论会显示在这里
>>> t = Template("My name is {{ person.first_name }}.")
>>> class PersonClass3:
...     def first_name(self):
...         raise AssertionError, "foo"
>>> p = PersonClass3()
>>> t.render(Context({"person": p}))
Traceback (most recent call last):
...
AssertionError: foo

>>> class SilentAssertionError(AssertionError):
...     silent_variable_failure = True
>>> class PersonClass4:
...     def first_name(self):
...         raise SilentAssertionError
>>> p = PersonClass4()
>>> t.render(Context({"person": p}))
u'My name is .'
Ivan 04-22 03:00

在 p = PersonClass4() t.render(Context({"person": p})) 运行时得不到示例结果,而是抛出异常: global name 'SilentAssertionError' is not defined 有人知道为什么吗?

Ivan 04-22 06:00

在 p = PersonClass4() t.render(Context({"person": p})) 运行时得不到示例结果,而是抛出异常: global name 'SilentAssertionError' is not defined 有人知道为什么吗? 原来进入IPython的方式是“python manage.py shell” 会出现上面的问题,现在改成“ipython” “from import django.conf import settings” “settings.configure()” 就没上面的问题了。应该是路径配置上出了问题。

qq345421243 05-08 08:39

加入这两句也可以 import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") 该句代码是从manage.py那里拷贝过来的

Faye euler 06-26 09:29

t.render(Context({"person": p})) 这句就报错, File "<console>", line 3, in first_name AssertionError: foo

chwwwie 04-15 07:31

raise AssertionError, "foo"后面要有两个回车,表示类定义完成

aaron 05-04 05:54

raise AssertionError,"foo" 输完一按回车就出错 显示 在逗号那有个 语法错误 line3 SyntaxError :invalid syntax 这是为啥

TTTsand 10-30 08:02

@aaron 看新版本的,raise AssertionError("foo")不报错

对这一段的评论会显示在这里

仅在方法无需传入参数时,其调用才有效。 否则,系统将会转移到下一个查找类型(列表索引查找)。

对这一段的评论会显示在这里

显然,有些方法是有副作用的,好的情况下允许模板系统访问它们可能只是干件蠢事,坏的情况下甚至会引发安全漏洞。

对这一段的评论会显示在这里

例如,你的一个 BankAccount 对象有一个 delete() 方法。 如果某个模板中包含了像 {{ account.delete }}这样的标签,其中account 又是BankAccount 的一个实例,请注意在这个模板载入时,account对象将被删除。

Lei 03-20 03:56

"包含了向 {{ account.delete }}这样的标签"中,“向”应该为“像”

Ryan 10-05 23:55

这个应该就是防止句点调用这个方法

yaoxiao16 05-06 02:04

不太明白

chuiwen 01-25 05:18

就是说render模板的时候,方法是确确实实被调用了,相应的操作也完成了,会对调用它的对象产生实实在在的影响。

吴某人 04-01 06:33

{{account.delete}}不应该是变量吗?怎么变成标签了?

对这一段的评论会显示在这里

要防止这样的事情发生,必须设置该方法的 alters_data 函数属性:

对这一段的评论会显示在这里
def delete(self):
    # Delete the account
delete.alters_data = True
C.F. 01-08 16:32

代码的indention不对。

weetao 01-20 12:23

def delete(self): # Delete the account alters_data = True 或者 def delete(self): # Delete the account delete.alters_data = True 应该都是一样的吧

weetao 01-20 12:24

汗 评注无法换行。。。

ode2free 04-07 18:53

delete.alters_data=true 要缩进

objectjava 05-25 07:48

alters_data属性是什么是禁止通过深度查找吗?

Linv 12-22 08:52

不能缩进 class TestCls(object): value = '123' def do() self.__class__.value = '456' do.alters_data = True

dracher 01-19 03:05

无需缩进,只是添加一个函数属性

yishuiliunian 03-03 07:27

这里这个 属性不是很明白啊

Scar_l 07-20 01:47

不缩进的话会报错吧?

jxl 11-13 20:17

不用缩进。这是在给delete 这个方法设置一个属性。设置属性当然要在这个方法外面设置。如果缩进的话,就代表在delete方法里使用delete,这又不是递归,会报错的吧。

匿名读者 03-20 05:14

no need to indent

Jasper 09-14 08:39

python是一门对缩进很严格的语言,所以缩进的地方一定要缩进

rcompass 10-10 13:25

delete.alters_data = True不能缩进,缩进就错了。

东汉总书记兼军委主席 12-25 02:44

这个文章写得很好!

落樱神斧 06-07 02:02

我总结一下吧: 没事儿就别用方法来做context!!!用个属性,或者列表又不麻烦!!

匿名读者 06-11 21:50

需要缩进的,不缩进报错

喵星人 12-19 10:41

应该解释为:为了防止delete这样的方法去误删除其他模板中的对象,使用alters_data = True来防止

1 01-04 08:09

谁的delete()设置该属性?模板?

吴某人 04-01 06:42

@喵星人 应该就是这样的

匿名读者 12-18 07:29

缩进会报错

电饭锅 02-04 12:45

确实是没有缩进的

对这一段的评论会显示在这里

模板系统不会执行任何以该方式进行标记的方法。 接上面的例子,如果模板文件里包含了 {{ account.delete }} ,对象又具有 delete()方法,而且delete()alters_data=True这个属性,那么在模板载入时, delete()方法将不会被执行。 它将静静地错误退出。

匿名读者 07-15 14:43

它将静静地错误退出???

对这一段的评论会显示在这里

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

Doming 04-05 15:32

例如:例如: 重复

匿名读者 07-29 02:02

kun

audax 08-23 10:06

mark

对这一段的评论会显示在这里
>>> from django.template import Template, Context
>>> t = Template('Your name is {{ name }}.')
>>> t.render(Context())
u'Your name is .'
>>> t.render(Context({'var': 'hello'}))
u'Your name is .'
>>> t.render(Context({'NAME': 'hello'}))
u'Your name is .'
>>> t.render(Context({'Name': 'hello'}))
u'Your name is .'
对这一段的评论会显示在这里

系统静悄悄地表示失败,而不是引发一个异常,因为这通常是人为错误造成的。 这种情况下,因为变量名有错误的状况或名称, 所有的查询都会失败。 现实世界中,对于一个web站点来说,如果仅仅因为一个小的模板语法错误而造成无法访问,这是不可接受的。

行之 12-12 15:37

请问: 若是由如此之小的粗心引起了错误,应该怎么样才能让系统通知程序员“此处发生了错误”。不抛出异常那就意味着很难找出bug了。。。

行之 12-12 16:16

在英文版页面找到以下评注,希望对大家有用: Daphna May 15th, 2009 3:43 a.m. "By default" implies that there's a way to change this behavior (and indeed it would be interesting to know how you can track these failures). You could say something about how to change it to refer readers to information about it. MJ Dec 7th, 2010 10:50 a.m. The below code will raise an exception for invalid Template variable. settings.py class InvalidVarException(object): def mod(self, missing): try: missing_str=unicode(missing) except: missing_str='Failed to create string representation' raise Exception('Unknown template variable %r %s' % (missing, missing_str)) def contains(self, search): if search=='%s': return True return False TEMPLATE_DEBUG=True TEMPLATE_STRING_IF_INVALID = InvalidVarException()

chacha 06-05 04:55

楼上 行之 说的好

1 01-04 08:13

测试的时候,你就会发现。

对这一段的评论会显示在这里

玩一玩上下文(context)对象

对这一段的评论会显示在这里

多数时间,你可以通过传递一个完全填充(full populated)的字典给 Context() 来初始化 上下文(Context) 。 但是初始化以后,你也可以使用标准的Python字典语法(syntax)向上下文(Context) 对象添加或者删除条目:

Scar_l 07-20 01:56

``上下文(Context)`` 的引号应该改用中文的引号吧

lazybios 10-11 09:59

该引号是加粗的意思,没有解析成功而已 不是真正的引号含义 具体见rst语法

莫小沫 11-24 12:33

将英语翻译的通俗易懂确实不是件简单的是,特别是对于这种技术性文档。像Context这样的词就很难翻,我感觉这个标题翻译成“捣鼓下Context对象”可能更好些。

July 02-20 13:11

也就是说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'
tonylifei 05-28 08:07

Context({}) 中双引号和单引号都可以用,但不知道有没有更深层次的区别

allblue 06-03 09:26

'和"应该没区别吧 在python语法里, 这二个是等价的 django里不大可能改动吧

alex 07-03 11:41

"玩一玩上下文(context)对象"这译文感觉怪怪的。。

浮生若茶 10-04 09:55

这里可以直接写成c=Context() 而后直接添加c['xx']='xx'

ls 12-02 02:35

‘玩一玩’...挑逗我们...

烟岚惜月 06-08 13:02

是python里基本上是单引号和双引号不分的么?

=_= 07-04 06:07

我擦。我分不出Context和字典有啥区别了

Andy 03-02 16:34

这里Context应该就是对字典进行了封装,所以可以将它视为字典。

对这一段的评论会显示在这里

基本的模板标签和过滤器

对这一段的评论会显示在这里

像我们以前提到过的,模板系统带有内置的标签和过滤器。 下面的章节提供了一个多数通用标签和过滤器的简要说明。

对这一段的评论会显示在这里

标签

对这一段的评论会显示在这里

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

匿名读者 07-29 02:22

kun

对这一段的评论会显示在这里
{% if today_is_weekend %}
    <p>Welcome to the weekend!</p>
{% endif %}
对这一段的评论会显示在这里

{% else %} 标签是可选的:

对这一段的评论会显示在这里
{% if today_is_weekend %}
    <p>Welcome to the weekend!</p>
{% else %}
    <p>Get back to work.</p>
{% endif %}
blackysy 07-01 06:11

Get back to work! o(╥﹏╥)o

对这一段的评论会显示在这里

Python 的“真值”

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里
  • 空列表([] )
  • 空元组(() )
  • 空字典({} )
  • 空字符串('' )
  • 零值(0 )
  • 特殊对象None
  • 对象False(很明显)
  • 提示:你也可以在自定义的对象里定义他们的布尔值属性(这个是python的高级用法)。
匿名读者 04-26 09:26

mark

初学者 10-13 07:15

为何我if的值是0还是还是执行了呢,帮我看看下面代码 def table(request): list_a = {'condition1':'0','condition2':'1','name1':'Tom','name2':'Jone'} list_b = {'Zhang':'33','Wang':'31','Li':'32','Zhao':'33'} dic = {'list1':list_a,'list2':list_b} return render_to_response('table.html',dic) 模版文件如下: {% if list1.condition1 %} <li> {{ list1.condition1 }} <li> Your Name is: {{ list1.name1 }} </li> {% elif list1.condition2 %} <li> {{ list1.condition2 }} <li> Your Name is: {{ list1.name2 }} </li> {% else %} <li> Your Name is: Nothing </li> {% endif %} 显示如下: 测试 if 语句: 0 Your Name is: Tom 奇怪了,判断值为0,居然还可以执行呢?

懒懒的 12-08 05:30

@初学者 你这个'0'是一个字符串,非空字符串本来就是True。

对这一段的评论会显示在这里

除以上几点以外的所有东西都视为True

李旭章 12-02 03:20

都视为`` True`` 建议改为 都视为“True”

Lang 09-06 11:22

嗯,这个是中文的双引号。

Lion 01-22 03:37

mk 11-14 07:42

''''这个是格式语法的,没有成功。

xudshen 11-29 08:23

ls一堆处女座

四轮自走地图炮 04-24 15:46

不是应该用英文引号“True”?

Kezon 08-13 12:03

空元组不应该是(,)吗

chuiwen 01-25 05:29

空元组不是(,),是( )

对这一段的评论会显示在这里

{% if %} 标签接受 andor 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not ),例如: 例如:

04-29 07:33

两个“例如:”

qcsky 12-24 15:00

考虑将它移到模板之外处理

Bindiry 07-27 09:20

第一行后面有两个“例如:例如:”

文祥 06-20 07:11

不能组合and和or,这个太不能理解了,不能因为逻辑上可能出错就禁止使用啊,这不是因噎废食么

文祥 06-20 07:31

刚刚试过了,1.4里面and和or是可以组合使用的,多个and或者多个or连接也是可以的,不过小括号还是不支持

初学路过 08-19 03:52

标签pyhon manage.py shell里不能运行呢? 然后view.py里试,会直接打印出代码: def lable_test(request): html = """{% if today_is_weekend %} <p>Welcome to the weekend!</p> {% endif %}""" return HttpResponse(html)

对这一段的评论会显示在这里
{% if athlete_list and coach_list %}
    Both athletes and coaches are available.
{% endif %}

{% if not athlete_list %}
    There are no athletes.
{% endif %}

{% if athlete_list or coach_list %}
    There are some athletes or some coaches.
{% endif %}

{% if not athlete_list or coach_list %}
    There are no athletes or there are some coaches.
{% endif %}

{% if athlete_list and not coach_list %}
    There are some athletes and absolutely no coaches.
{% endif %}
对这一段的评论会显示在这里

{% if %} 标签不允许在同一个标签中同时使用 andor ,因为逻辑上可能模糊的,例如,如下示例是错误的: 比如这样的代码是不合法的:

对这一段的评论会显示在这里
{% if athlete_list and coach_list or cheerleader_list %}
匿名读者 11-15 07:56

mark

qcz 12-02 07:21

mark

Harrison 05-03 03:09

mark

Xavier 07-15 05:13

楼上们,你们mark了又有什么用= =!

urmyfaith 09-13 07:27

mark是何解?

misutt 10-18 05:44

ls 就是做个标记的意思,mark了的确没啥用啊

django 11-26 06:45

那我既要用and又要用or该怎么办?

Rying 01-08 07:30

楼上的往下看就知道了

sinoyster 07-01 02:53

mark

sinoyster 07-04 01:51

{% if %} 标签不允许在同一个标签中同时使用 and 和 or ,因为逻辑上可能模糊的

cj 11-08 06:18

ls

泥奏凯 10-23 12:37

可以

对这一段的评论会显示在这里

系统不支持用圆括号来组合比较操作。 如果你确实需要用到圆括号来组合表达你的逻辑式,考虑将它移到模板之外处理,然后以模板变量的形式传入结果吧。 或者,仅仅用嵌套的{% if %}标签替换吧,就像这样:

dogxxgod 05-06 03:25

why not ?

sapjax 07-20 08:03

把复杂的逻辑放到模板之外,还是有好处的。

keyman 10-24 04:09

我觉得这个还是十分方便的,简洁十分好理解

ls 12-02 02:40

把复杂的逻辑放到模板之外不利于封装模块化,紧耦合?

Xavier 07-15 05:14

这个有点奇怪啊

leon.zhu 09-27 07:59

模板主要作用,简单逻辑处理产生必要的模板输出。所以复杂逻辑应该放到模板之外

mingming 11-23 02:37

这里的“系统不支持用圆括号来组合比较操作”说是的是模板不是python吧?

对这一段的评论会显示在这里
{% if athlete_list %}
    {% if coach_list or cheerleader_list %}
        We have athletes, and either coaches or cheerleaders!
    {% endif %}
{% endif %}
对这一段的评论会显示在这里

多次使用同一个逻辑操作符是没有问题的,但是我们不能把不同的操作符组合起来。 例如,这是合法的:

sadrfdsafdsafsda 07-10 14:40

fsdfdsfdsfds

匿名读者 08-05 03:02

这个很纠结!!! 需要改进

zlleah 12-19 00:43

"但是我们不能把不同的操作符组合起来",什么意思???不同的操作符多次使用???

lixuequa 09-17 09:24

就是 一个{% %}内部不能同时使用 or and not 但是可以使用多次or and not

Lynn 10-06 06:48

<%if A and/or B%> <%if A or not B%> <%if not A and B%> <%if A and B and C …… %> <%if A or B or C …… %> 类似以上都是合法的,但下面的是非法的: <%if A and b or c%>

rcompass 10-10 13:27

Django 1.5版本中,此限制已取消,可以混合使用and 和 or了

对这一段的评论会显示在这里
{% if athlete_list or coach_list or parent_list or teacher_list %}
对这一段的评论会显示在这里

并没有 {% elif %} 标签, 请使用嵌套的{% if %} 标签来达成同样的效果:

李旭章 12-02 03:21

建议将`` {% if %}`` 的双引号改为中文的。 “{% if %}”

xl 01-09 10:38

淡疼

xl 01-09 10:38

闲的

浮生若茶 10-04 09:59

尽量把需要计算或者逻辑较强的语句放到模版之外

Kevin 06-10 14:57

现在已经有了{% elif %} 标签: https://docs.djangoproject.com/en/dev/ref/templates/builtins/ ------- 以后的链接,可能失效,官网一定会更新,大家注意评论时间戳。

fiy fish 07-23 16:09

{% elif %}就是 else if 的意思吧

Xavier 07-15 05:15

感觉有点反人类啊,这模板语法。

mihello 08-01 13:17

django 1.6 已经有elif

匿名读者 08-05 09:38

无语啊。

urmyfaith 09-13 07:29

不是已经有elsif了么? 2014年9月13日 15:29:52

chuiwen 01-25 05:33

已经有elif了

gepoe 03-29 07:53

楼上正解

潘磊 03-08 06:51

并没有 {% elif %} 标签, 请使用嵌套的`` {% if %}`` 标签来达成同样的效果

流沙 11-13 07:13

现在已经有{% elif %}了,这个网站已经很久没有更新了,大家看的时候需要注意,也不知道哪些跟着作者说并没有{% elif %}的人是为了搞笑还是另有企图

对这一段的评论会显示在这里
{% if athlete_list %}
    <p>Here are the athletes: {{ athlete_list }}.</p>
{% else %}
    <p>No athletes are available.</p>
    {% if coach_list %}
        <p>Here are the coaches: {{ coach_list }}.</p>
    {% endif %}
{% endif %}
对这一段的评论会显示在这里

一定要用 {% endif %} 关闭每一个 {% if %} 标签。

张斌 01-12 17:01

恩,一定要注意,这个开发中往往会忽略,这个和程序大括号一样,需要一对~

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里

例如,给定一个运动员列表 athlete_list 变量,我们可以使用下面的代码来显示这个列表:

对这一段的评论会显示在这里
<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}
</ul>
小菜 12-28 11:09

class person: def __init__(self,name): self.name = name athlete_list=[person('John'),person('Joe')] c = Context({'athlete_list':athlete_list}) t.render(c)

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里
{% for athlete in athlete_list reversed %}
...
{% endfor %}
张玉炎 08-28 09:21

真不错

ls 12-02 02:46

反向迭代 ?好爽的语法

xZero 01-09 07:39

神马是反向迭代··

匿名读者 01-16 13:57

@xZero 就是从后面元素向前面开始遍历

JokER 03-09 05:45

reversed(athlete_list)

gshmu 05-13 09:47

DESC

heliar 07-14 14:46

这个写法真不错

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里
{% for athlete in athlete_list %}
    <h1>{{ athlete.name }}</h1>
    <ul>
    {% for sport in athlete.sports_played %}
        <li>{{ sport }}</li>
    {% endfor %}
    </ul>
{% endfor %}
小海绵 03-16 06:08

<li></li>是什么意思

lxy 11-05 06:58

去看一下HTML,答案就有了

对这一段的评论会显示在这里

在执行循环之前先检测列表的大小是一个通常的做法,当列表为空时输出一些特别的提示。

匿名读者 09-29 10:14

城区

Zhou 07-15 02:30

There are no athletes. Only computer programmers.哈哈哈哈哈哈

lee 12-04 07:03

哈哈哈哈,只有程序猿......

对这一段的评论会显示在这里
{% if athlete_list %}
    {% for athlete in athlete_list %}
        <p>{{ athlete.name }}</p>
    {% endfor %}
{% else %}
    <p>There are no athletes. Only computer programmers.</p>
{% endif %}
对这一段的评论会显示在这里

因为这种做法十分常见,所以for 标签支持一个可选的{% empty %} 分句,通过它我们可以定义当列表为空时的输出内容 下面的例子与之前那个等价:

anhuizf 02-20 13:34

这里不能翻译为列表吧, 列表怎么能用athlete_list.name 这样用?

Charles 07-18 12:06

列表能这么用吧

python 08-05 03:08

empty的结束点在哪里???

yuxc 10-22 13:48

each athlete is a dict.

ponxu 07-03 14:54

django的模版这个empty字句不错!!

sapjax 07-20 08:06

empty不需要结束标签

Snapshot 11-01 03:36

@anhuizf 可以的你构造Context的时候如下即可:c = Context({'athlete_list': [{'name': 'haha'}, {'name': 'hehe'}]})

ls 12-02 02:50

好厉害的功能,empty相当于 if athlete=='',他跟随for结束

xZero 01-09 07:45

比php方便

box 01-13 15:44

mark

jwfy 02-28 01:27

这个点赞!!!

牛三金 04-21 16:49

django逻辑运算的语法与PYTHON不一致。

stevenlee87 06-13 07:19

不错的评注!

heliar 07-14 14:51

列表应该是iterator:迭代器吧

jackling 01-04 11:57

这个不错

袁龙 01-16 13:21

There are no athletes. Only computer programmers. 没人看到这个吐槽吗??? “这里没有运动员,有的只是一群死宅程序员。”

qdw 03-06 01:59

在此之前我都是通过使用{% if %}...{% for %}...{% endfor %}{% else %}{% endif %}来实现这种效果的,现在有{% empty %}确实方便了许多!

Cc 03-26 11:51

|就是一个输出文本 233

对这一段的评论会显示在这里
{% for athlete in athlete_list %}
    <p>{{ athlete.name }}</p>
{% empty %}
    <p>There are no athletes. Only computer programmers.</p>
{% endfor %}
对这一段的评论会显示在这里

Django不支持退出循环操作。 如果我们想退出循环,可以改变正在迭代的变量,让其仅仅包含需要迭代的项目。 同理,Django也不支持continue语句,我们无法让当前迭代操作跳回到循环头部。 (请参看本章稍后的理念和限制小节,了解下决定这个设计的背后原因)

ls 12-02 02:52

这句话没理解,怎么退出的?

东汉总书记兼军委主席 12-25 02:55

不支持退出意思就是没有类似break或者return的语法吧

xiaopanddxiong 08-03 07:37

意思是:循环不能通过break或者continue中断 只能改变循环体,使其仅仅包含你期望遍历的部分

对这一段的评论会显示在这里

在每个{% for %}循环里有一个称为forloop 的模板变量。这个变量有一些提示循环进度信息的属性。

对这一段的评论会显示在这里

forloop.counter 总是一个表示当前循环的执行次数的整数计数器。 这个计数器是从1开始的,所以在第一次循环时 forloop.counter 将会被设置为1。

对这一段的评论会显示在这里
{% for item in todo_list %}
    <p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
jwfy 02-28 01:28

这个点赞!!!一直想要这个功能

chuiwen 01-25 05:42

相当于python语法的enumerate

对这一段的评论会显示在这里

forloop.counter0 类似于 forloop.counter ,但是它是从0计数的。 第一次执行循环时这个变量会被设置为0。

goofy 09-10 08:17

python以简单实用著称,django为什么要提供forloop.counter0和forloop.counter两个功能一样的东西呢

书记 11-11 08:17

按照python来多好,名字用counter,计数从0开始

huangz 01-01 01:45

@goofy forloop.count是以1开始计数 forloop.count0是以0开始计数 @书记 每次从0开始计算,符合程序员的逻辑,但不符合普通阅览者的逻辑。

sapjax 07-20 08:10

从0开始计算, 模板里面难道不能 forloop.counter + 1么

meamin9 08-16 14:15

forloop.counter + 1不支持这么写吧

朕本布衣 12-18 07:20

是不是可以写成 forloop.last|add:"1"

对这一段的评论会显示在这里

forloop.revcounter 是表示循环中剩余项的整型变量。 在循环初次执行时 forloop.revcounter 将被设置为序列中项的总数。 最后一次循环执行中,这个变量将被置1。

对这一段的评论会显示在这里

forloop.revcounter0 类似于 forloop.revcounter ,但它以0做为结束索引。 在第一次执行循环时,该变量会被置为序列的项的个数减1。

对这一段的评论会显示在这里

forloop.first 是一个布尔值,如果该迭代是第一次执行,那么它被置为[](#id12) 在下面的情形中这个变量是很有用的:

对这一段的评论会显示在这里

Inline literal start-string without end-string.

Doming 04-11 14:30

那么它被置为'''' -> 那么它被置为True

aliff 03-13 01:59

楼上正解

sapjax 07-20 08:13

用{% if not forloop.counter0 %} 也可以啊,虽然不好理解点

gegev 05-07 03:12

forloop.first能够直观的展现出其用意,还是有必要存在的。倒是forloop.counter的存在没必要,forloop.counter0应被定义为forloop.counter,然后forloop.counter0这个变量应被删掉。

对这一段的评论会显示在这里
{% for object in objects %}
    {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
    {{ object }}
    </li>
{% endfor %}
mihello 08-01 14:32

qdw 03-06 02:03

这么强大!

Tiy 04-09 13:28

li为啥是个单标签?

aaron 05-04 07:02

@ li 因为 那两个<li>是在分支结构中不可能同时存在 只会有一个与后面的</li>对应

aaron 05-04 07:02

@ Tiy因为 那两个<li>是在分支结构中不可能同时存在 只会有一个与后面的</li>对应

helloworld 07-09 14:51

是不是第一循环的 <li class='first'> {{ object }} </li> 后面的循环都是 <li> {{ object }} </li>

对这一段的评论会显示在这里

forloop.last 是一个布尔值;在最后一次执行循环时被置为True。 一个常见的用法是在一系列的链接之间放置管道符(|)

baiye123 12-05 03:32

这里英文原版为“forloop.first is a Boolean value set to True if this is the first time through the loop. ” 所以应该是如果是第一次循环,forloop.first为true,不应该翻译为最后一次吧?

行之 12-12 16:49

回ls,这里写的是forloop.last,而不是forloop.first,forloop.first已经在上文解释过了。

Zyzsdy 10-13 04:58

"|"不应该被翻译为“管道符”吧。。。

lgy 11-10 08:01

略坑。。看到下面的逗号才明白过来

Joe 02-25 06:51

“|”不应翻译为管道。这里就是一个竖杠字符而已。

ryan 03-28 13:47

@joe 人家说的管道符,又没说管道

cass 05-29 15:10

他是說forloop.last耶

Ignora 01-24 05:41

只是'|'这个字符人家叫它管道符而已...

对这一段的评论会显示在这里
{% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}
书记 11-11 08:19

虽然能看懂,还是写成缩进的比较好

python 08-05 03:21

上面的模板可能会产生如下的结果==>上面的模板会产生如下的结果

匿名读者 10-11 14:03

| 不应该译为管道符,容易误解,应该就是指"竖线",输出的文本而已。

行之 12-12 16:53

同意ls,只是输出文本而已。这翻译看得我有点迷糊了。

mayao11 03-28 02:14

这个地方误解很严重,看了三遍才明白,请作者务必按其他网友的说法修正。另外考虑用缩进会清晰的多

Scar_l 07-20 02:45

这么写的话我差点没看到那个"|"

sapjax 07-20 08:16

就是啊,想了半天管道,过滤什么的,原来是竖线...

peter 10-23 00:16

坑爹啊啊啊啊啊管道符

DDGG 12-29 11:48

的确,这个“管道符”太容易误解了,幸好我聪明,看第二遍的时候就明白了。

woody 01-26 02:20

坑死了,就是个字符,自己缩进一下就明白了。 {% for link in links %} {{ link }} {% if not forloop.last %} | {% endif %} {% endfor %}

woody 01-26 02:20

晕,把我的缩进去除了。。。

chris 06-15 13:38

沒開發過網站的話真的會誤解...

lincy 08-12 12:06

在python里确实称为管道

swk 10-12 12:55

对应的context怎么写啊

加菲猫 02-08 06:32

"|"只是个字符,看看下面的例子. import datetime from django.template import Template, Context raw_template = """ {% for link in links %}{{ link }}{% if not forloop.last %} # {% endif %}{% endfor %} """ t = Template(raw_template) now=datetime.datetime.now() nowtime=now.time() c = Context({ 'links': ['xx','yy','zz'] }) print t.render(c) ==> xx | yy | zz

加菲猫 02-08 06:36

等价于: {% for link in links %} {{ link }} {% if not forloop.last %} | #输出用|分割 {% endif %} {% endfor %}

Joe 02-25 06:53

“|”不应翻译为管道。这里就是一个竖杠字符而已。 原文:A common use for this is to put pipe characters between a list of links: 直译是管道。

ermao 03-07 13:59

这里就是说,如果不是最后一个link,会打印一个 '|' 字符。最后一个则不会打印。

Ignora 01-24 05:46

只是'|'这个字符人家叫它管道符而已,谁也没说这个地方作用起管道的作用啊,自己想当然断章取义却说人家误导你?

Ignora 01-24 05:53

缩进之后输出格式不一样,要么自己搞清楚怎么解决要么就不要随随便便说人家写的不对!

对这一段的评论会显示在这里

上面的模板可能会产生如下的结果:

对这一段的评论会显示在这里
Link1 | Link2 | Link3 | Link4
对这一段的评论会显示在这里

另一个常见的用途是为列表的每个单词的加上逗号。

Paulrui 02-21 07:58

这里应该不是为每个单词添加逗号,是为列表中的单词(除了最后一个)的每次单词后面添加一个逗号

aaron 05-04 07:05

楼上正解

对这一段的评论会显示在这里
Favorite places:
{% for p in places %}{{ p }}{% if not forloop.last %}, {% endif %}{% endfor %}
lincy 08-12 12:08

为啥不用缩进格式写代码?!太不pythonic了吧!

urmyfaith 09-13 08:10

确实,这里的代码都没有缩进,但是缩进后后,输出就变了...ITS A QUESTION

对这一段的评论会显示在这里

forloop.parentloop 是一个指向当前循环的上一级循环的 forloop 对象的引用(在嵌套循环的情况下)。 例子在此:

lgy 11-10 08:05

parentloop感觉很好用的样子,吼吼

对这一段的评论会显示在这里
{% for country in countries %}
    <table>
    {% for city in country.city_list %}
        <tr>
        <td>Country #{{ forloop.parentloop.counter }}</td>
        <td>City #{{ forloop.counter }}</td>
        <td>{{ city }}</td>
        </tr>
    {% endfor %}
    </table>
{% endfor %}
simin 06-08 08:38

代码中“#”后面不会被注释掉吗??

cstriker1407 08-14 06:16

不会被注释掉,这里不是python程序代码,是模板代码,类似html。

dikou 09-07 01:46

第六行的{{ forloop.counter }}是不是应该是第七行的{{city}},第七行不要?

dikou 09-07 01:52

{{ forloop.parentloop.counter }}应该是{{ forloop.parentloop.country }}

mr.liu 06-03 10:09

回复楼上的,forloop.parentloop.counter 是正确的,他是在调用上级循环的forloop对象,然后使用该对象的counter,显示上级的循环次数。所以“<td>Country #{{ forloop.parentloop.counter }}</td>”显示的是外层for循环的循环次数,“<td>City #{{ forloop.counter }}</td>”显示的是内层for循环的循环次数。如果不明白,请自己写两个类方法测试。

Ignora 01-24 05:56

这一段代码的作用是输出第n个国家的第n个城市的名称

对这一段的评论会显示在这里

forloop 变量仅仅能够在循环中使用。 在模板解析器碰到{% endfor %}标签后,forloop就不可访问了。

对这一段的评论会显示在这里

Context和forloop变量

对这一段的评论会显示在这里

在一个 {% for %} 块中,已存在的变量会被移除,以避免 forloop 变量被覆盖。 Django会把这个变量移动到 forloop.parentloop 中。通常我们不用担心这个问题,但是一旦我们在模板中定义了 forloop 这个变量(当然我们反对这样做),在 {% for %} 块中它会在 forloop.parentloop 被重新命名。

流云 07-17 03:19

没搞明白。。。什么意思?

行之 12-12 17:05

这段翻译有点奇怪。 说的是: 当模板存在一个名叫“forloop”的变量时,为了防止for块中的forloop被覆盖,将会把同名的forloop变量移至forloop.parentloop去。也就是forloop.parentloop.forloop (不知道这样说对不对)

Also 12-13 05:38

反正知道不要定义一个名为forloop的变量就好了。。。

文祥 06-20 08:07

为什么Django不禁止定义forloop变量?

sapjax 07-20 08:21

应该不对啊,如果forloop已经被覆盖和重命名了,还怎么去访问forloop.parentloop呢? 没弄明白,求解释

django 08-17 07:24

应该不对啊,如果forloop已经被覆盖和重命名了,还怎么去访问forloop.parentloop呢? 没弄明白,求解释 他会把你定义的forloop 放到系统原始的 forloop.parentloop 这个就代表的是你的对象,forloop 仍然还是forloop

zlleah 12-19 01:08

我也表示没太懂,mark一下

Anti 03-30 12:02

是不是说嵌套的for循环中,外层的有个forloop,内层也有个forloop。 然后为了防止覆盖, 在内层对外层forloop的引用就用forloop.parentloop来表示。 个人理解 不对请轻喷

shuijing 04-19 12:56

I can't understand clearly, So, marking!

halicando 05-27 02:14

看上面的例子,前半句话中所谓的“移除变量”,是指在第一个for循环中已存在的变量(country),该变量不受内嵌的第二个for循环的forloop变量约束,而是受第一个for循环的forloop变量(为第二个for循环的forloop变量的父类即第二个循环中使用的变量forloop.parentloop)约束;后半句话说的是,尽量不要用forloop作为模板变量名,如果使用,则该变量名将会被自动重新命名为forloop.parentloop而避免与该for循环中已经存在的forloop变量发生冲突。(话说直接禁止这样命名,抛出个错误不就得了嘛,真是的。)

world000 07-03 03:17

@django 的意思是对的吧。

coco 08-31 13:36

有些不理解,我们在模板中定义了forloop,他会重新定义forloop以覆盖我们所定义的。然后我们定义的变量放到forloop.parentloop中,然后在系统的forloop使用过后,再将我们定义的还原回来,有点类似C++的局部变量和全局变量的关系么??是这个意思不???

Jasper 09-17 06:44

貌似应该是这样的:因为你要用forloop的变量去提取数组中的数据,但是例子中有两个数组,子循环中的forloop表示的是子循环中数组的数据,但是为了要提取父循环中的数据,django把父循环中数据移到一个forloop.parentloop中以示区别。个人感觉!!

rcompass 10-10 13:31

举个例子就很清楚了: >>> t = Template(''' ... {% for item in items %} ... #{{ forloop.counter }}: {{ item }} ... *{{ forloop.parentloop }} ... {% endfor %} ... ''') >>> c = Context({'items': items, 'forloop': 1000}) >>> print t.render(c) { forloop.parentloop }} 会被替换为1000

jwfy 02-28 01:37

@Jasper 我感觉这个说的对,第一层的for里面的参数到了第二层for的时候 会被移除,但是我们必须调用他,所以 我们就用forloop.parentloop 来接收之前移除的变量 再来调用

dolphin 03-03 09:03

mark

Morty 06-29 09:06

totally fooled ,mark

老孟 09-26 06:23

for标签翻译的有点乱

袁龙 01-16 13:32

我的理解是:如果你定义了名字叫forloop的变量,那么进入第一层for循环的时候,你的变量就不能再用forloop访问了,而要用forloop.parentloop访问。此时的forloop变量是for循环自带的标签模板变量。

chuiwen 01-25 05:54

看原文: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 don’t 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.

匿名读者 09-20 06:27

意思就是如果你自己定义了forloop变量,那么在for循环中的部分会被循环自带的forloop变量覆盖,在for循环外的部分你仍可以使用你自己定义的forloop。如果你一定要在for循环内部使用自己定义的forloop的话那么在内部你应该用forloop.parentloop表示你自己定义的那个变量。

cad0420 07-04 16:18

不不不,我理解的意思是,不是定义forloop这个变量。是指代码中有一个变量a,但是在for循环中也定义了一个块作用域的变量a(比如:{% for a in a_list %} ...{% endfor %}里面),那么你在这个for循环里面调用外层的变量a,就要用 forloop.parentloop.a 去调用。 但是你如果在代码中定义了一个forloop变量的话,for循环中的forloop.parentloop就被相应地重写了。因此不要随便瞎创建叫做forloop变量。

wayne bruce 09-08 07:16

真心看不懂啊。。。。

test 03-04 08:55

http://blog.51cto.com/ggbond/1440427,,, 这里有个示例可以看看

Ignora 01-24 06:05

那么假如我在这个块里面要使用'forloop.parentloop'怎么办...

电饭锅 02-05 06:57

上上楼博客里 是正解

koala 09-25 01:44

给大家举个例子 {# 手欠,自己先造了一个变量 #} {% with forloop='我才是正宗的forloop' %} 外层前:{{ forloop }} {# 预期:输出“我才是正宗的forloop” #} {% for item in items %} 循环里:{{ forloop }} {# Django 自带的循环对象 #} 循环里parentloop:{{ forloop.parentloop }} {# 被挪走的“正版” #} {% endfor %} 外层后:{{ forloop }} {# 又恢复成“我才是正宗的forloop” #} {% endwith %}

对这一段的评论会显示在这里

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

sapjax 07-20 08:27

不如改成{% if user equal currentuser %}

Snapshot 11-01 05:58

使用硬编码字符的时候需要注意如下: t = Template("""{% ifequal a "b" %} Welcome! {% endifequal%}""") 如果使用的不是三引号,硬编码字符应该与外面的引号相反

woody 01-26 02:23

前面加上 r 好了

wk 11-17 14:00

支持多个条件判断吗? 比如 if a or b 或者 if a and b

jwfy 02-28 01:38

ls 这前面不是写了么?

Morty 06-29 10:00

莫名的笑了,写者说话很实在,点赞

匿名读者 12-18 07:51

这个标签已经过时了,现在直接用比较符号 There’s really no reason to use {% ifequal %} or {% ifnotequal %} anymore, unless you’re the nostalgic type. The operators supported are ==, !=, <, >, <=, >=, in and not in, all of which work like the Python operators, in addition to and, or and not, which were already supported.

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里

下面的例子比较两个模板变量 usercurrentuser :

对这一段的评论会显示在这里
{% ifequal user currentuser %}
    <h1>Welcome!</h1>
{% endifequal %}
对这一段的评论会显示在这里

参数可以是硬编码的字符串,随便用单引号或者双引号引起来,所以下列代码都是正确的:

匿名读者 07-29 07:41

什么叫做硬编码奥?

匿名读者 05-27 13:57

硬编码,我理解就是非变量,即字符串等不能变的东东

Allen Ren 04-08 05:18

这里应该指的是不可变数据类型吧

对这一段的评论会显示在这里
{% ifequal section 'sitenews' %}
    <h1>Site News</h1>
{% endifequal %}

{% ifequal section "community" %}
    <h1>Community</h1>
{% endifequal %}
对这一段的评论会显示在这里

{% if %} 类似, {% ifequal %} 支持可选的 {% else%} 标签:

Labi Kyo 10-23 06:29

{% else%} -> {% else %}

02-03 09:39

ifequal 和 if 不知道是否可以套用

Snapshot 11-01 06:03

@何 可以嵌套使用的

lgy 11-10 08:46

urmyfaith 09-13 08:16

@ 收的到提醒?这....玩微博呢? ==!

mr.liu 05-25 13:34

‘@’估计就是个提示作用吧,他在指明他回答的谁。

blackysy 07-01 06:17

不要在意这些细节

对这一段的评论会显示在这里
{% ifequal section 'sitenews' %}
    <h1>Site News</h1>
{% else %}
    <h1>No News Here</h1>
{% endifequal %}
对这一段的评论会显示在这里

只有模板变量,字符串,整数和小数可以作为 {% ifequal %} 标签的参数。下面是合法参数的例子:

对这一段的评论会显示在这里
{% ifequal variable 1 %}
{% ifequal variable 1.23 %}
{% ifequal variable 'foo' %}
{% ifequal variable "foo" %}
对这一段的评论会显示在这里

其他任何类型,例如Python的字典类型、列表类型、布尔类型,不能用在 {% ifequal %} 中。 下面是些错误的例子:

对这一段的评论会显示在这里
{% ifequal variable True %}
{% ifequal variable [1, 2, 3] %}
{% ifequal variable {'key': 'value'} %}
对这一段的评论会显示在这里

如果你需要判断变量是真还是假,请使用 {% if %} 来替代 {% ifequal %}

桃子 11-08 09:10

感觉{% ifequal %}是{% if %}的一个特例,只是为了方便而设置的吗?

mywjch 11-19 05:21

应该是,前面就说了“比较两个变量的值并且显示一些结果实在是个太常见的需求了”。

十三少 09-22 06:21

好像不是这样吧,if也不支持等于和不等比较

chuiwen 01-25 06:02

if 是支持 == 运算的。

Snapeliu 06-13 03:22

现在if在一般情况貌似不支持 ==

吴某人 04-01 11:01

django里面的if语句不能够用==做判断是吗?

对这一段的评论会显示在这里

就像HTML或者Python,Django模板语言同样提供代码注释。 注释使用 {# #}

对这一段的评论会显示在这里
{# This is a comment #}
对这一段的评论会显示在这里

注释的内容不会在模板渲染时输出。

对这一段的评论会显示在这里

用这种语法的注释不能跨越多行。 这个限制是为了提高模板解析的性能。 在下面这个模板中,输出结果和模板本身是 完全一样的(也就是说,注释标签并没有被解析为注释):

对这一段的评论会显示在这里
This is a {# this is not
a comment #}
test.
不满 06-16 07:56

一折行就不是注释了

匿名读者 01-20 03:39

前后标签必须在同一行

对这一段的评论会显示在这里

如果要实现多行注释,可以使用{% comment %} 模板标签,就像这样:

dengj 06-05 07:21

直接使用如下的方法不是更好么? #第一行注释# #第二行注释# #第三行注释#

byrain 07-17 08:51

看起来会比较难受吧

cbxjj 06-26 08:17

大段的注释你这每行都写不是作死么

urmyfaith 09-13 08:24

多行注释的话,为什么不用c预言的/**/ ???? 2014年9月13日 16:24:37

对这一段的评论会显示在这里
{% comment %}
This is a
multi-line comment.
{% endcomment %}
对这一段的评论会显示在这里

过滤器

三千君 09-27 15:30

mark

qcz 12-02 08:28

mark

对这一段的评论会显示在这里

就象本章前面提到的一样,模板过滤器是在变量被显示前修改它的值的一个简单方法。 过滤器使用管道字符,如下所示:

对这一段的评论会显示在这里
{{ name|lower }}
python 08-05 03:45

管道太奇怪了 直接用方法多好!!!

dawncold 08-09 06:05

用管道也许是为了给方法传递参数

yang 05-16 10:01

感觉模板挺麻烦。直接能用代码多好

lazybios 09-25 03:12

附录在哪里啊?

nkuflk 11-13 08:54

@python 感觉用管道才是精华

匿名读者 08-27 06:50

模板是为了web前端和代码能切开,这样代码只管写代码。。。你难道让程序猿处理页面布局?

wanggang 12-21 06:54

{{ name|lower }} 和 {{ name.lower }} 一样吗?

对这一段的评论会显示在这里

显示的内容是变量 {{ name }} 被过滤器 lower 处理后的结果,它功能是转换文本为小写。

对这一段的评论会显示在这里

过滤管道可以被 套接 ,既是说,一个过滤器管道的输出又可以作为下一个管道的输入,如此下去。 下面的例子实现查找列表的第一个元素并将其转化为大写。

对这一段的评论会显示在这里
{{ my_list|first|upper }}
YueZheng 11-15 08:22

这里管道中是什么?my_list的属性还是方法啊

YueZheng 11-15 08:24

哦,不是方法也不是属性。就是过滤器,想偏了

wind 07-05 10:28

my_list.first().upper() 可以这样理解吧?

LinkYun 11-26 03:18

不懂first这里是做什么操作?

吴某人 04-01 11:17

过滤器就是过滤器,不是方法或者属性,不带.的,也不带()的

yanan 05-24 07:56

有点像终端的pip。 command 里常用,原来的stdout变成了下一个指令的stdin。不同的是这里是过滤器

yanan 05-24 07:57

有点像终端的pipe。 command 里常用,原来的stdout变成了下一个指令的stdin。不同的是这里是过滤器

对这一段的评论会显示在这里

有些过滤器有参数。 过滤器的参数跟随冒号之后并且总是以双引号包含。 例如:

对这一段的评论会显示在这里
{{ bio|truncatewords:"30" }}
lincy 08-12 12:48

多参咋办,用逗号分隔么?

jako 09-01 16:33

@lincy 每个{{ }} 里都应该只有一个参数把?多个参数的话应该是用多个括号

Harry 12-25 03:02

truncatewords:"30" 指的是取前30个单词,还是取前30个字母 ?

Harry 12-25 03:14

知道了,下面说了是取变量bio的前30个词。

urmyfaith 09-13 08:38

取出前30个单词组.不是字母.

冯日 11-06 06:54

取30个单词最后加上...

mr.liu 05-27 08:59

前30个词,这词之间须是用空格分隔。

对这一段的评论会显示在这里

这个将显示变量 bio 的前30个词。

Harry 12-25 03:14

知道了,下面说了是取变量bio的前30个词。

jwfy 02-28 01:40

ls 提醒一下 这30个是英文的 如果是中文的则要使用slice

对这一段的评论会显示在这里

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

Tian Siyuan 03-22 03:04

原文也错了,应该是附录E。

spring 01-21 09:44

没想到length竟然以过滤器出现

Matt 01-30 06:19

http://djangobook.py3k.cn/appendixF/ 各种附录改最后面的一个字母即可

Ignora 01-24 07:04

就是附录F,附录E反而会进不去

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里

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

dikou 09-07 02:14

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

Ignora 01-24 07:05

addslashed感觉是个神器

对这一段的评论会显示在这里
{{ pub_date|date:"F j, Y" }}
对这一段的评论会显示在这里

格式参数的定义在附录F中。

对这一段的评论会显示在这里

length : 返回变量的长度。 对于列表,这个参数将返回列表元素的个数。 对于字符串,这个参数将返回字符串中字符的个数。 你可以对列表或者字符串,或者任何知道怎么测定长度的Python 对象使用这个方法(也就是说,有 __len__() 方法的对象)。

对这一段的评论会显示在这里

理念与局限

shaotianjie 08-13 10:00

mark

MTH 01-21 09:44

谢谢分享!

对这一段的评论会显示在这里

现在你已经对Django的模板语言有一些认识了,我们将指出一些特意设置的限制和为什么要这样做 背后的一些设计哲学。

对这一段的评论会显示在这里

相对与其他的网络应用的组件,模板的语法很具主观性,因此可供程序员的选择方案也很广泛。 事实上,Python有成十上百的 开放源码的模板语言实现。 每个实现都是因为开发者认为现存的模板语言不够用。 (事实上,对一个 Python开发者来说,写一个自己的模板语言就象是某种“成人礼”一样! 如果你还没有完成一个自己的 模板语言,好好考虑写一个,这是一个非常有趣的锻炼。 )

CubeQ 12-22 06:56

"模块的羽凡很具观性",有点费解,是否是“主观性”?

冬冬 08-23 09:07

这方面讲的不错

kuber 12-31 07:42

"More than any other component of Web applications": 和其它web 应用的组件比起来 "and programmers’ opinions vary wildly", 而且程序员们的各种观点也大相径庭, 同时我觉得and 似乎不翻出来也行

WYM 03-21 13:58

"成十上百"?

群众纷纷 10-04 09:42

翻译成“数十个”会更好吧

ls 12-02 03:29

成人礼?厄...我还没呢...

chiedey 04-12 12:06

没想到LS年纪青青

PoppinL 05-16 06:49

相对与->相对于

Xavier 07-15 05:22

我还没成人,囧

虎头蔓 01-06 06:06

成十上百->成百上千

Neinaa 04-16 09:12

mark~ 25+成年姑婆有空回来成年礼

对这一段的评论会显示在这里

明白了这个,你也许有兴趣知道事实上Django并不强制要求你必须使用它的模板语言。 因为Django 虽然被设计成一个FULL-Stack的Web框架,它提供了开发者所必需的所有组件,而且在大多数情况 使用Django模板系统会比其他的Python模板库要 更方便 一点,但是并不是严格要求你必须使用 它。 你将在后续的“视图中应用模板”这一章节中看到,你还可以非常容易地在Django中使用其他的模板语言。

Chika 03-20 17:09

“视图中应用模板”建议上下文对照翻译为“在视图中使用模板”

对这一段的评论会显示在这里

虽然如此,很明显,我们对Django模板语言的工作方式有着强烈的偏爱。 这个模板语言来源于World Online的开发经验和Django创造者们集体智慧的结晶。 下面是关于它的一些设计哲学理念:

对这一段的评论会显示在这里

业务逻辑应该和表现逻辑相对分开 。我们将模板系统视为控制表现及表现相关逻辑的工具,仅此而已。 模板系统不应提供超出此基本目标的功能。

对这一段的评论会显示在这里

出于这个原因,在 Django 模板中是不可能直接调用 Python 代码的。 所有的编程工作基本上都被局限于模板标签的能力范围。 当然, 有可能写出自定义的模板标签来完成任意工作,但这些“超范围”的 Django 模板标签有意地不允许执行任何 Python 代码。

jim 04-10 08:07

业务逻辑跟表现逻辑分开;开发的过程中,有时候觉得python不够强大,不能再模板语言中直接调用python语言,限制太多,这时候就想着各种改,希望可以这样,又可以那样,最终搞得脱离python的设计理念,然后又回到了原点,白费一番功夫

对这一段的评论会显示在这里

语法不应受到 HTML/XML 的束缚 。尽管 Django 模板系统主要用于生成 HTML,它还是被有意地设计为可生成非 HTML 格式,如纯文本。 一些其它的模板语言是基于 XML 的,将所有的模板逻辑置于 XML 标签与属性之中,而 Django 有意地避开了这种限制。 强制要求使用有效 XML 编写模板将会引发大量的人为错误和难以理解的错误信息,而且使用 XML 引擎解析模板也会导致令人无法容忍的模板处理开销。

对这一段的评论会显示在这里

假定设计师精通 HTML 编码 。模板系统的设计意图并不是为了让模板一定能够很好地显示在 Dreamweaver 这样的所见即所得编辑器中。 这种限制过于苛刻,而且会使得语法不能像目前这样的完美。 Django 要求模板创作人员对直接编辑 HTML 非常熟悉。

杏noclip 09-24 13:07

说的很好

匿名读者 06-25 03:46

Django expects template authors to be comfortable editing HTML directly

对这一段的评论会显示在这里

假定设计师不是 Python 程序员 。模板系统开发人员认为:模板通常由设计师而非程序员来编写,因此不应被假定拥有Python开发知识。

starof 02-04 07:25

模板通常由设计师而非程序员来编写,因此不应被假定拥有Python开发知识。-------但是设计师却被假定必须拥有模板标签的知识,,这样真的好吗??呵呵,设计师应该喜欢所见即所得的东东,这给人家难度又增加了一大截,就是从一个坑到另一个坑

Ignora 01-24 07:27

有同ls的疑问,在使用django的时候并不能像DW或者VSCode编写HTML一样所见即所得,那么为什么不直接把HTML和Python完全分开,分别实现业务逻辑和表现逻辑呢?

对这一段的评论会显示在这里

当然,系统同样也特意地提供了对那些 Python 程序员进行模板制作的小型团队的支持。 它提供了一种工作模式,允许通过编写原生 Python 代码进行系统语法拓展。 (详见第十章)

对这一段的评论会显示在这里

目标并不是要发明一种编程语言 。目标是恰到好处地提供如分支和循环这一类编程式功能,这是进行与表现相关判断的基础。

对这一段的评论会显示在这里

在视图中使用模板

jerry 04-24 17:14

mark

MyloveEs 02-22 08:24

mark

对这一段的评论会显示在这里

在学习了模板系统的基础之后,现在让我们使用相关知识来创建视图。 重新打开我们在前一章在 mysite.views 中创建的 current_datetime 视图。 以下是其内容:

对这一段的评论会显示在这里
from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
对这一段的评论会显示在这里

让我们用 Django 模板系统来修改该视图。 第一步,你可能已经想到了要做下面这样的修改:

对这一段的评论会显示在这里
from django.template import Template, Context
from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    t = Template("<html><body>It is now {{ current_date }}.</body></html>")
    html = t.render(Context({'current_date': now}))
    return HttpResponse(html)
没钱没闲 03-19 02:16

写到这里,我才真的可以用IDE写东西,以上那些还没办法用IDE,说实话,我现在用pycharm感觉都不会使用shell了。

谢营长 06-17 08:53

为什么不是试试sublime

heliar 07-15 02:59

一直使用vim。。。

mihello 08-02 04:12

win 用sublime,linux 用vim

Voidy 08-27 03:42

同楼上

吴某人 04-01 11:34

Python编程环境一直用的Python2,文本编辑一直用的nano,交互器用的shell。。

wayne bruce 09-08 07:30

大神都用vim 我等菜鸡 用pycharm

Ignora 01-24 07:35

之前的东西也可以作为.py文件单独运行,只不过要在.py文件开始处设置系统环境变量

blackysy 07-01 06:49

我觉得pycharm很方便,查看源代码方便,排查问题也很效率~

对这一段的评论会显示在这里

没错,它确实使用了模板系统,但是并没有解决我们在本章开头所指出的问题。 也就是说,模板仍然嵌入在Python代码里,并未真正的实现数据与表现的分离。 让我们将模板置于一个 单独的文件 中,并且让视图加载该文件来解决此问题。

mr.liu 05-27 09:51

mark

对这一段的评论会显示在这里

你可能首先考虑把模板保存在文件系统的某个位置并用 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)
Rh 02-03 09:49

1.6版本已经不需要这么做了。不需要寻找模板路径。已经默认

LeonWong 04-28 08:23

终于讲到重点了

sjs 10-30 16:53

finally...

Adoo 12-19 04:32

在windows环境下测试完,发现路径里面的\符号要换成\\,否则python会找不到文件。

kiyomi 10-26 10:31

是将上面的代码保存为html吗?

camellhf 01-31 13:38

@kiyomi 不是,这里还是views.py里的代码,上面的html路径只是用来说明代码里fp = open()里的路径应该是html文件所在的路径

Zelin_Chan 11-29 02:59

TypeError: context must be a dict rather than Context. 将html = t.render(Context({'current_date':now})) 改为html = t.render({'current_date':now})即可

Memory 03-30 12:34

@Adoo 不用这么麻烦吧,直接转义就行啦。例: with open(r'D:\demo\mytemplate.html') as f: content = f.read()

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里
  • 它没有对文件丢失的情况做出处理。 如果文件 mytemplate.html 不存在或者不可读, open() 函数调用将会引发 IOError 异常。
  • 这里对模板文件的位置进行了硬编码。 如果你在每个视图函数都用该技术,就要不断复制这些模板的位置。 更不用说还要带来大量的输入工作!
  • 它包含了大量令人生厌的重复代码。 与其在每次加载模板时都调用 open()fp.read()fp.close() ,还不如做出更佳选择。
对这一段的评论会显示在这里

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

对这一段的评论会显示在这里

模板加载

周陈斌 03-14 03:34

直接在你的app中建立templates文件夹,把html等文件放入其中,不用在setting.py文件中设置,就可以了。

zl 07-25 07:52

一楼具体指哪个文件夹?

zl 07-25 08:50

谷歌搜的,加入下边代码到settings.py中,同时我是在manage.py同一级目录创建的templates文件夹: from os.path import join TEMPLATE_DIRS = (join(BASE_DIR, 'templates'), )

test 06-23 06:52

. &nbsp; .

王洪章 04-10 02:48

Django1.8.7以上版本后,配置静态模块存放路径不用采取文章中推荐的方法。只需要在TEMPLATES里面的DIR里添加路径即可

对这一段的评论会显示在这里

为了减少模板加载调用过程及模板本身的冗余代码,Django 提供了一种使用方便且功能强大的 API ,用于从磁盘中加载模板,

对这一段的评论会显示在这里

要使用此模板加载API,首先你必须将模板的保存位置告诉框架。 设置的保存文件就是我们前一章节讲述ROOT_URLCONF配置的时候提到的 settings.py

对这一段的评论会显示在这里

如果你是一步步跟随我们学习过来的,马上打开你的settings.py配置文件,找到TEMPLATE_DIRS这项设置吧。 它的默认设置是一个空元组(tuple),加上一些自动生成的注释。

对这一段的评论会显示在这里
TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)
Tabrisfdu 05-04 08:27

这里的目录名不可有非ASCII字符

菲菲 02-24 07:16

为什么django 1.6 自动生成的settings.py 没有TEMPLATE_DIRS选项

zzZ 02-27 09:19

我用的1.6.2也没有TEMPLATE_DIRS,求高手指点

godsallen 03-11 09:59

同样没有啊,增么办?

03-19 12:01

1.5里面是那样设置的,但1.6默认是不需要设置的,默认的寻找路径是在app下面新建一个templates目录,所有的模板放进去,系统会自己找到的~ 从知乎里找到的。。

sho 03-26 07:26

version 1.6.2 ls,不设置的话还是会出错啊。。

wff0316 04-26 05:20

在BASE_DIR下面加入TEMPLATE_DIRS = ( os.path.join(BASE_DIR, 'templates').replace('\\','/'), )就可以了

老孟 09-26 07:06

1.7也没有这配置

console 10-20 08:03

1.8 也没有这配置

bee3134 11-04 08:43

1.7没有TEMPLATE_DIRS,求指导!

afei 04-14 03:33

在TEMPLATE的DIRS中添加模板目录即可,例如: TEMPLATES = [ { ...... 'DIRS': [ os.path.join(BASE_DIR, 'templates'), ], ...... }, ]

fellow 05-30 17:05

1.8的文档里面是这么描述的: A new setting was introduced in Django 1.8: TEMPLATES. All existing template-related settings were deprecated. During the deprecation period, Django will create a backwards-compatible TEMPLATES based on the TEMPLATE_* settings if you don’t define it yourself.

bitson 06-08 09:16

我的是1.8版本,在下面这段里加入“mysite”,然后django会自动在mysite里找到templates文件夹的。记住,templates文件夹放在mysite文件夹下面: INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'mysite', )

ochhh 06-23 06:51

. .

ochhh 06-23 06:54

1.8官方文档上是在TEMPLATES = [ ]里面 'DIRS': [ ]那里添加的。。。。。。 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ # insert your TEMPLATE_DIRS here ], 'APP_DIRS': True,

吴某人 04-01 11:40

1.9表示TEMPLATE下面会有一个DIRS选项的。它后面是一个空的【】

chaos 08-02 10:00

django1.9没有TEMPLATES_DIR的情况,在setting.py中TEMPLATES下有个空DIR,里面填写os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),亲测可用

chaos 08-02 10:03

django1.9没有TEMPLATES_DIR的情况,在setting.py中TEMPLATES下有个空DIR,里面填写os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),亲测可用。另,模板文件夹templates在setting.py同级目录下

lvze 09-20 06:56

新版本的Django中没有这个设置选项而是改为TEMPLATES这选项下有‘DIRS’一项为一个列表,默认里面为空,会加载app下templates文件夹中的模板。可以在这个选项列表中自行加入指定的模板路径。

泥奏凯 10-23 13:55

在Django1.5之后的版本中,查找TEMPLATES配置项代替TEMPLATE_DIR的配置,是一样的

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里
TEMPLATE_DIRS = (
    '/home/django/mysite/templates',
)
Tkey 08-06 13:54

谁可以指导下这里可不可以用相对路径 怎么用

Tkey 08-06 13:56

囧。。。。下面看到了

特里 09-03 02:20

每次用相对路径都报错,感觉不会再爱了。

Henry Zivers 10-11 11:20

'/home/%usrname%/djcode/mysite/templates'

Hanna 11-01 16:08

为什么我的settings.py中没有Template_DIRS呢

qiweijie1314iliting 11-14 15:11

qiweijie1314iliting 11-14 15:11

+1

duet 11-26 06:03

setting.py没有Template_dir啊

duet 11-26 06:03

settings.py没有TEMPLATE_DIRS啊

苏艾丰 12-02 07:22

@duet,@Hanna ,settings.py中没有Template_DIRS,可以自己填上去

Vincent 12-29 16:17

@苏艾丰 , 添加了 TEMPLATE_DIRS 但是没有作用是为什么呢?服务器重起了的。

Rh 02-03 09:49

1.6版本已经不需要这么做了。不需要寻找模板路径。已经默认

July 02-20 13:17

原来如此,1.6真知棒

Max 04-10 21:34

TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')] https://docs.djangoproject.com/en/1.6/intro/tutorial02/

jstech 06-28 06:11

Django version 1.6。默认到app列表制定的目录查找templates目录,在该目录中,找到第一个与视图函数中些的目标模板,找到后渲染页面。所以关键在于,需要将你的app,添加到app列表中。那么如何添加?settings.py文件中:INSTALLED_APPS项目,大概在35行。INSTALLED_APPS = ( # 注意:去掉所有中文注释 'mysite',# 这里本来不包含mysite,如果还有其他的也加进来。 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.admin', #'bg', # add others app )

jstech 06-28 06:13

Django version 1.6。默认到app列表制定的目录查找templates目录,在该目录中,找到第一个与视图函数中些的目标模板,找到后渲染页面。所以关键在于,需要将你的app,添加到app列表中。那么如何添加?settings.py文件中:INSTALLED_APPS项目,大概在35行。 # 注意:去掉所有中文注释。 # 这里本来不包含mysite,如果还有其他的也加进来。 INSTALLED_APPS = ( 'mysite', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.admin', #'bg', # add others app )

hellokatewj 07-04 10:57

这里应该要用绝对路径

mihello 08-02 05:02

@Max,正解

sqsowen 11-17 13:12

加这句:TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')] 和在这里INSTALLED_APPS = ( ......加'mysite'.

monkeyfather 05-03 14:04

TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] 1.8 https://docs.djangoproject.com/en/1.8/intro/tutorial02/

gnotiac 06-10 17:38

1.8的请看楼上。尝试过继续用TEMPLATE_DIR,发现loader没有将路径载入。

安铺靓仔 07-19 13:00

django3将TEMPLATES 的DIRS设为BASE_DIR

安铺靓仔 07-19 13:14

上面那条有错误

对这一段的评论会显示在这里

下面是一些注意事项:

对这一段的评论会显示在这里

你可以任意指定想要的目录,只要运行 Web 服务器的用户可以读取该目录的子目录和模板文件。 如果实在想不出合适的位置来放置模板,我们建议在 Django 项目中创建一个 templates 目录(也就是说,如果你一直都按本书的范例操作的话,在第二章创建的 mysite 目录中)。

ben 05-22 16:43

这里应该说明的一点是必须是绝对路径,而不是相对路径。我有点疑问,在新浪的SAE中这个地方时如何使用的? Don't forget to use absolute paths, not relative paths.

Tick 06-11 04:02

mac: ~/Documents/DJango/mysite/mysite/templates

yg 06-18 13:45

跟BEN有同样的问题,想想应该会设计成支持相对路径才对

benson 08-09 08:42

是出于怎样的考虑而必须使用绝对路径?

vose 12-18 14:53

用绝对路径么?

Haeckel 08-14 13:58

既然要用os.path.join(BASE_DIR,'templates'),那么,templates目录是要创建在哪里??? 项目叫mysite,但是项目目录中还有一个mytest目录,我是Django 1.6.5

Haeckel 08-14 13:59

Django 1.6.5,templates要创建在项目目录中,也就是....django/mysite/templates

xu 07-04 11:23

不止一个目录才要加comma吧。 不是油BASE_DIR嘛

Ignora 01-24 07:46

用绝对路径的话,部署到服务器的时候不会出错吗???

对这一段的评论会显示在这里

如果你的 TEMPLATE_DIRS只包含一个目录,别忘了在该目录后加上个逗号。

对这一段的评论会显示在这里

Bad:

对这一段的评论会显示在这里
# Missing comma!
TEMPLATE_DIRS = (
    '/home/django/mysite/templates'
)
sean.yao 02-10 07:58

这个Bad和下面的Good实例有什么区别吗?

martin 03-04 08:40

Good比bad多了个“,”号

objectjava 05-26 02:19

@sean.yao:python基本语法中规定元祖为一个元素的情况下使用元素,

ivan 04-22 09:34

千万别写错了,settings.py中还有个TEMPLATE_LOADER我就是把路径写到这了,调死我了。

icedream 10-17 07:51

别复制路径,坑爹解析成\t了。。

summerlv 11-24 01:55

Deprecated since version 1.8: Set the DIRS option of a DjangoTemplates backend instead. # 1.8 以后的版本,使用 DIRS 这个环境变量来设 source: https://docs.djangoproject.com/en/1.8/ref/settings/

对这一段的评论会显示在这里

Good:

对这一段的评论会显示在这里
# Comma correctly in place.
TEMPLATE_DIRS = (
    '/home/django/mysite/templates',
)
对这一段的评论会显示在这里

Python 要求单元素元组中必须使用逗号,以此消除与圆括号表达式之间的歧义。 这是新手常犯的错误。

jim 04-10 08:41

原来在单元组元组中必须使用逗号的原因是为了消除与圆括号表达式之间的歧义

对这一段的评论会显示在这里

如果使用的是 Windows 平台,请包含驱动器符号并使用Unix风格的斜杠(/)而不是反斜杠(),就像下面这样:

liqin 12-23 06:54

反斜杠(\)

zhongqi 02-08 04:51

不能像html那样使用.表示当前目录,使用..表示上一级目录么?

looly 01-20 06:53

@zhongqi Don't forget to use absolute paths, not relative paths.这是settings.py中的注释

对这一段的评论会显示在这里
TEMPLATE_DIRS = (
    'C:/www/django/templates',
)
Lang 09-06 12:03

即使 r'c:\www\django\templates', 这样也不行

zlleah 12-19 03:15

@Lang,我用了r'c:\www\django\templates',可以啊

skyxxx 03-06 06:55

相信大家都是这么写的吧 os.path.join(BASE_DIR, 'templates').replace('\\', '/'), 大家肯定将templates这个文件夹放到mysite 这个目录下了。 BASE_DIR = os.path.dirname(os.path.dirname(__file__)) 他获得的地址是当前这个模块的路径,所以路径中少了个mysite ,导致找不到这个模板文件

uc 11-05 09:03

setting.py里没有TEMPLATE_DIRS,这个有点怪,手动加进去的情况,还没有试过!

EvilFinder 02-22 06:09

Django1.7好像已经不适用这种加载模板的方法了吧?

匿名读者 08-24 07:05

其实可以写到TEMPLATES 这里面定义了DIRS

对这一段的评论会显示在这里

最省事的方式是使用绝对路径(即从文件系统根目录开始的目录路径)。 如果想要更灵活一点并减少一些负面干扰,可利用 Django 配置文件就是 Python 代码这一点来动态构建 TEMPLATE_DIRS 的内容,如: 例如:

Lion 01-22 05:34

建议:“可利用 Django 配置文件就是 Python 代码这一点来动态构建 TEMPLATE_DIRS 的内容”改为“可利用Python 代码在Django 配置文件中动态构建 TEMPLATE_DIRS 的内容”

对这一段的评论会显示在这里
import os.path

TEMPLATE_DIRS = (
    os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)
wyatt 12-27 06:27

这里没必要是import os.path吧,直接import os即可。

wang 04-20 09:00

只引入需要的最简的模块

艾西可 12-20 07:06

我是在win2008下部署的环境,ECLIPSE + PYDEV 书中提及的对模板目录的配置对我的环境无效, 必须改成: TEMPLATE_DIRS = ( ''.join([os.path.dirname(__file__),'/Template/TEMP']).replace('\\','/'), )

choosewang 07-24 04:59

用'./templates' 也行。。

匿名读者 03-09 08:37

太强大了

cabbageKK 05-16 18:15

@choosewang 我试了一下,'./templates'不行也

suzhiqiang 01-11 03:21

`` os.path.dirname(__file__)`` 将会获取"(__file__)"文件所在的目录,即settings.py 所在的目录(本例中为mysite)。然后由os.path.join这个方法将此目录与templates目录进行连接,linux下形成如mysite/templates;windows下形成如mysite\templates。

meng 03-10 11:36

感谢楼上

madao 04-24 16:55

看到此处的python代码忽然感到很亲切...

echo 07-02 02:34

为什么我在python中提示name '__file__' is not defined?

无名小卒 11-08 06:56

TEMPLATE_DIRS=( os.path.join(os.path.dirname(__file__),'../templates').replace('\\','/'), ) 这样就可以把templates文件夹放在上一层目录了,如果需要,可以放在其他目录,但是要修改'../templates'

Adoo 12-19 05:55

Django_1.7版本亲测,templates文件放在和settings文件同一个目录下,settings文件中的BASE_DIR语句不要修改它,因为settings文件下面的语句会用到它。在下面自己添加一句TEMPLATE_DIRS=(os.path.join(os.path.dirname(__file__),'templates').replace('\\','/'),就可以成功寻找到模版。另外有同学把templates文件创建在和manage.py同一个目录下的话,那么TEMPLATE_DIR语句就要多添加一个函数os.path.dirname(),因为这个函数就是显示自身文件的目录地址的,在使用多一次这个函数,就可以把地址修改到原来目录的上一层。

herrdu 04-30 08:01

出现错误 NameError: name '__file__' is not defined 改用下面的方法 os.path.join(os.path.dirname(os.path.realpath('__file__')), 'templates').replace('\\','/')

kunnka wong 05-31 03:58

TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] django 1.9版本,直接在TEMPLATE下面的DIRS添加模板路径就可以了,亲测可用

对这一段的评论会显示在这里

这个例子使用了神奇的 Python 内部变量 __file__ ,该变量被自动设置为代码所在的 Python 模块文件名。 os.path.dirname(__file__) 将会获取自身所在的文件,即settings.py 所在的目录,然后由os.path.join 这个方法将这目录与 templates 进行连接。如果在windows下,它会智能地选择正确的后向斜杠”“进行连接,而不是前向斜杠”/”。

liqin 12-23 06:20

向后斜杠“\”

stranbird 05-09 06:27

*所在的文件夹

goofy 09-10 09:22

这里os.path.join要和str.join区别开

goofy 09-10 09:28

__file__ 等于 argv[0] 吗

Chika 03-21 01:07

最后一句应该是: 然后确保使用的都是正斜杠“/”,而不是反斜杠“\”(在windows中)

looly 01-20 06:56

“神奇的”应该翻译成“魔法”比较好吧?这句就是“这个例子使用了Python的魔法变量__file__”

spacewalker 08-19 03:13

还是“神奇的”比较好吧

suzhiqiang 01-11 03:22

`` os.path.dirname(__file__)`` 将会获取"(__file__)"文件所在的目录,即settings.py 所在的目录(本例中为mysite)。然后由os.path.join这个方法将此目录与templates目录进行连接,linux下形成如mysite/templates;windows下形成如mysite\templates。

对这一段的评论会显示在这里

在这里我们面对的是动态语言python代码,我需要提醒你的是,不要在你的设置文件里写入错误的代码,这很重要。 如果你在这里引入了语法错误,或运行错误,你的Django-powered站点将很可能就要被崩溃掉。

东汉总书记兼军委主席 12-25 03:18

被崩溃掉翻译不妥,改为崩溃掉即可。

对这一段的评论会显示在这里

完成 TEMPLATE_DIRS 设置后,下一步就是修改视图代码,让它使用 Django 模板加载功能而不是对模板路径硬编码。 返回 current_datetime 视图,进行如下修改:

对这一段的评论会显示在这里
from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    t = get_template('current_datetime.html')
    html = t.render(Context({'current_date': now}))
    return HttpResponse(html)
athos 03-08 13:53

最好能描述一下,测试此例子时,需要模板目录里新建一个文件, 文件名为:current_datetime.html。文件内容为: <html><body>It is now {{ current_date }}.</body></html>

qq345421243 05-09 03:10

楼上说得极是

qq345421243 05-09 04:05

为什么像下面这样设置全路径报错说找不到模板文件呢? t = get_template('C:/Inetpub/wwwroot/django/mysite/mysite/template/current_datetime2.html')

qq345421243 05-09 04:06

为什么像下面这样设置全路径报错说找不到模板文件呢? t = get_template('C:/Inetpub/wwwroot/django/mysite/mysite/template/current_datetime2.html') 直接在浏览器中打入该文件地址显示文件存在啊,地址路径和文件名都没错误

~ 01-06 10:55

同LS,我的也是,求解

cy 01-11 02:25

需要在settins.py 加上类似的参数吧 TEMPLATE_DIRS=( 'D:/TEMPLATES', )

bger 02-27 12:28

为什么我的报错TemplateDoesNotExist

skyxxx 03-06 06:46

这个太让我崩溃了 os.path.join(BASE_DIR, 'templates').replace('\\', '/'), 设置的好好的,怎么就报错呢

starof 03-19 07:46

@athos 后面有说到创建模板current_datetime.html

ak47 03-21 09:01

django 1.6.2 如下设置,正常 TEMPLATE_DIRS = ( (BASE_DIR+'/templates').replace('\\','/'), ) http://stackoverflow.com/questions/17168256/template-does-not-exist

ak47 03-21 09:02

django 1.6.2<br/> 如下设置,正常。<br/> TEMPLATE_DIRS = ( (BASE_DIR+'/templates').replace('\\','/'), )<br/> http://stackoverflow.com/questions/17168256/template-does-not-exist

Django1.6 04-06 16:32

1.6下到django/conf/global_settings.py里面设置TEMPLATE_DIRS = ('F:/pythonDjango/mysite/mysite/templates',)

Yang 07-01 13:39

设置template目录方法: 1、在manage.py同级目录下新建文件夹 ,名为template 2、修改setting.py: import os.path Temp_Path = os.path.realpath('.') BASE_DIR = os.path.dirname(os.path.dirname(__file__)) STATIC_ROOT = '' STATIC_URL = '/static/' TEMPLATE_DIRS = ( Temp_Path +"/template" )

bee3134 11-04 09:47

1.7下实践证明在urls同级目录下新建templates文件夹

gyyzyp 01-18 02:33

@bger 我的也是 找到解决方法没

www 02-21 14:55

把templates文件夹建在和manage.py同级的文件夹里,而不是settings, 因为settings是在mysite/mysite文件夹里,它寻找模板是在mysite/templates而不是mysite/mysite/templates

charlie_cen 04-17 09:27

我用的django1.8版本,出现无法找到template下面模版文件 setting.py文件配置 import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) TEMPLATE_DIRS = ( os.path.join(BASE_DIR, 'templates'), ) 然后是views.py文件配置 from django.http import HttpResponse from django.template import Context import datetime from django.template.loader import get_template def current_datetime(request): now = datetime.datetime.now() t = get_template('current_datetime.html') html = t.render(Context({'current_date':now})) return HttpResponse(html) urls.py配置 url(r'^time/$', current_datetime), 错误提示: TemplateDoesNotExist at /time/ current_datetime.html Request Method: GET Request URL: http://127.0.0.1:8000/time/ Django Version: 1.8 Exception Type: TemplateDoesNotExist Exception Value: current_datetime.html 没找出问题,求大神帮助!谢谢

风间雅 05-17 13:52

django1.8里面需要将模板的路径加到setting.py中的TEMPLATES里的DIRS,像这样子:TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.path.join(BASE_DIR, 'templates').replace('\\', '/'), ], ......(省略后面的内容了.)

smallerpig 07-06 05:54

版本1.8使用楼上方法解决!

kiyomi 10-26 11:01

为什么他说global name 'get_template' is not defined

01 11-05 16:28

@kimoyi 你应该在 import 的时候漏掉了 template.loader ?

吴某人 04-02 13:27

要在创建的template文件里创建一个current_datetime.html,不然的话在浏览器中输入url后将会出现TemplateDoesNotExist的页面错误。错误指向current_datetime

haha 08-01 08:41

1.8版本以上的只需要在template文件夹下新建一个current_time.html文件就可以了

lvze 09-20 07:24

新版本的Django中render函数参数直接接收一个字典,而不再是Context

Tang 11-11 07:00

from mysite.views import hello,hours_ahead,current_datetime 这样子写没有错吧,为什么刚开始好使 之后不知道做了什么,就开始报错了:ImportError: cannot import name current_datetime 这个事为什么

小海绵 03-16 07:36

弄半天文件名写错了,是tempaltes不是template,只要把建的app加入到settings里面,就能自动找到app下面的templates文件夹

zhanghuarong 07-01 07:27

html=r.render(Context({'Currnet_date':now})) 此行出错 context must be a dict rather than Context. 用的django 1.11.2版本,get_template貌似弃用Context()了

xiaopanddxiong 08-03 09:19

用的最新版本django 1.11 执行时候报错: context must be a dict rather than Context. 将代码html = t.render(Context({'current_date': now}))改为:html = t.render({'current_date': now})即可,去掉Context()

Jim 08-06 09:54

新版不能用context传递参数了,得用 render_to_response()

lvhua 11-08 03:35

执行时候报错: context must be a dict rather than Context. 将代码html = t.render(Context({'current_date': now}))改为:html = t.render({'current_date': now})即可,去掉Context()

谢康乐 11-19 14:18

@lvze正解,1.11的版本,render接收的参数是字典,不需要借助Context了,也即: now=datetime.datetime.now() t=get_template('curtime.html') d={'cur_time':str(now)} html=t.render(d)#不再是render(Context(d)) return HttpResponse(html)

匿名读者 12-01 02:22

报错:context must be a dict rather than Context. 解决: t = get_template("index.html") d = {"name": "Jack", "items":["item1", "item2", "item3"]} html=t.render(d) return HttpResponse(html) 说明:render一个字典即可,不用传Context对象

lee 12-04 09:22

ls正解

pbox 12-19 12:57

django 1.11 TypeError,改写为html = t.render({'current_date': now})

lyz 12-24 13:57

django2.0 templates文件夹和mysite在同一级 'DIRS': [os.path.join(BASE_DIR,'templates')] 成功

泽木 04-19 08:53

给力!!!

zenith 08-17 16:15

楼上正解!!!1.11的版本,render接收的参数是字典,不需要借助Context了。 html = t.render(Context({'current_date': now}))去掉Context()就可以解决type error:context must be a dict rather than Context.

匿名读者 04-23 07:43

django2.2 templates文件夹和manage.py在同一级 'DIRS': [os.path.join(BASE_DIR,'templates')] 亲测可以

匿名读者 05-09 11:27

是的

匿名读者 05-09 11:29

这里有个坑,改成,html = t.render({'offset':dt})

匿名读者 10-24 09:52

django1.8 python2.7 亲测,2个需要修改: 1. TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'mysite/templates').replace('\\', '/'),],...}] 2. c 直接写成字典形式,不用context

tester 01-03 08:57

django 3.0版本后, t = get_template('mytemplate.html') # c = Context({'current_date': now}) html = t.render({'current_date': now})

tester 01-03 08:58

django 3.0版本后, t = get_template('mytemplate.html') html = t.render({'current_date': now})

对这一段的评论会显示在这里

此范例中,我们使用了函数 django.template.loader.get_template() ,而不是手动从文件系统加载模板。 该 get_template() 函数以模板名称为参数,在文件系统中找出模块的位置,打开文件并返回一个编译好的 Template 对象。

jason 12-11 08:52

模块的位置 改为 模板的位置

对这一段的评论会显示在这里

在这个例子里,我们选择的模板文件是current_datetime.html,但这个与.html后缀没有直接的联系。 你可以选择任意后缀的任意文件,只要是符合逻辑的都行。甚至选择没有后缀的文件也不会有问题。

objectjava 05-26 02:36

此处没有写清楚。get_template()中的文件名一定要与硬盘中的文件名相同,但是后缀名要去掉[都]也可以

raven 11-25 08:02

楼上你试过没就在那边扯淡了?

paulzhao 08-05 09:57

可以在创建这个模板的时候不指定后缀名,或者随便指定一个后缀名,但是在传给get_template这个方法的时候,一定是硬盘上是什么就传什么,硬盘上带后缀的就一定要写对后缀。否则还是报找不到的错误。

NigelYang 11-05 09:26

那就是说硬盘上是个文本文件也可以?而且能写入?

吴某人 04-02 13:35

如果你创建的模板文件带上后缀(比如我创建的就带.html的后缀),那么在调用的时候就一定要带上后缀,不然就找不到文件

Admin 09-30 07:35

1

对这一段的评论会显示在这里

要确定某个模板文件在你的系统里的位置, get_template()方法会自动为你连接已经设置的 TEMPLATE_DIRS目录和你传入该法的模板名称参数。比如,你的 TEMPLATE_DIRS目录设置为 '/home/django/mysite/templates',上面的 get_template()调用就会为你找到 /home/django/mysite/templates/current_datetime.html 这样一个位置。

dimens 04-10 07:19

传入该法--->传入该方法

Henry Zivers 10-11 11:16

Change into '/home/%usrname%/djcode/mysite/templates' maybe better.

plom 10-15 02:36

好强大

对这一段的评论会显示在这里

如果 get_template() 找不到给定名称的模板,将会引发一个 TemplateDoesNotExist 异常。 要了解究竟会发生什么,让我们按照第三章内容,在 Django 项目目录中运行 python manage.py runserver 命令,再次启动Django开发服务器。 接着,告诉你的浏览器,使其定位到指定页面以激活current_datetime视图(如 http://127.0.0.1:8000/time/ )。假设你的 DEBUG项设置为 True,而你有没有建立current_datetime.html 这个模板文件,你会看到Django的错误提示网页,告诉你发生了 TemplateDoesNotExist 错误。

lotuser 09-14 08:17

而你有没有建立current_datetime.html ---> 而你又没有建立current_datetime.html

nina 10-10 08:13

运行 python manage.py runserver 怎么会有invalid \x escape 的错误啊

ont 10-25 07:24

图挂了呃

SYB 11-26 06:51

http://www.djangobook.com/en/2.0/_images/missing_template.png

hehe 12-16 16:07

搞了半天,终于没错了,templates文件夹要在manage.py同一级,我误会了os.path.dirname(os.path.dirname(__file__))的意思

fsda 04-14 09:11

1.8在 TEMPLATES = [ { 'DIRS': [ os.path.join(BASE_DIR, 'templates'), ], ***** 这个位置提交就可以找到模板了 不用再另外写了

猪头哥哥 11-30 02:54

在1.11版本 不需要配置Template路径了哦

对这一段的评论会显示在这里

图 4-1: 模板文件无法找到时,将会发送提示错误的网页给用户。

对这一段的评论会显示在这里

该页面与我们在第三章解释过的错误页面相似,只不过多了一块调试信息区: 模板加载器事后检查区。 该区域显示 Django 要加载哪个模板、每次尝试出错的原因(如:文件不存在等)。 当你尝试调试模板加载错误时,这些信息会非常有帮助。

yp 11-02 08:16

看不到图。。

Sphinx 07-09 21:49

出现一个问题, t = get_template('current_datetime.html'),会出现上述错误TemplateDoesNotExist ,但是当 t = get_template('current_datetime.html '),注意看,html后有一个空格,然后网页能正常显示了,这是怎么回事呢?

sapjax 07-20 09:35

@Sphinx 没发现这个问题

网中人 08-21 06:12

@sapjax 你的文件名是不是后面多了一个空格?

Rain 12-10 16:01

TemplateDoesNotExist at /time/ why...

Sky 11-12 07:09

django 1.7中添加一句“TEMPLATE_DIRS=[os.path.join(BASE_DIR,'template'),]”就可以正常加载模板了,记住templates文件夹与manage.py同级

吴某人 04-02 13:38

请教大家应该怎么在网页中显示图片呢?我在current_datetime.html文件中加入html的语句<img src="here is photo's path">网页中加载的图是挂掉的。。

对这一段的评论会显示在这里

接下来,在模板目录中创建包括以下模板代码 current_datetime.html 文件:

对这一段的评论会显示在这里
<html><body>It is now {{ current_date }}.</body></html>
对这一段的评论会显示在这里

在网页浏览器中刷新该页,你将会看到完整解析后的页面。

项超 02-05 07:04

我采用硬编码方法和采用模板方式显示的页面时间格式不一样。 time now is Feb. 5, 2012, 2:59 p.m. 这是采用模板方式显示的时间格式 time is now 2012-02-05 15:02:44.142162 这是采用硬编码方式显示的时间格式。 用模板的时候这中间转换有什么不用吗?

lioyuo 07-05 05:33

AttributeError at /time/ 'SafeUnicode' object has no attribute 'status_code'

lg 05-21 15:10

我的显示no module named views 是怎么回事?求救

桃子 11-08 13:11

for lg: 你看你的文件夹里面的是 view.py 还是 views.py 好像默认是 view.py 的。

bger 02-27 13:37

输入的地址是什么啊?需要跟上html文件名么

sssy 05-24 14:37

在这句话t = get_template('current_datetime.html ') 里有UnicodeDecodeError怎么办?在mysite里多了wsgi.py这个文件是因为安装了什么数据库么???求指点

sssy 05-24 14:43

将后缀html改为txt同时模板也改为txt文件就好了,不明就里。。。

yubg 07-28 18:20

在templates文件下按照要求做了 current_datetime.html 文件,刷新http://127.0.0.1:8000/time,还是显示错误: TemplateDoesNotExist at /time/ current_datetime.htmlRequest Method: GET Request URL: http://127.0.0.1:8000/time/ Django Version: 1.6.5 Exception Type: TemplateDoesNotExist Exception Value: current_datetime.html

yubg 07-28 18:29

我知道问题所在了:current_datetime.html 文件的扩展名多了,

wayne 08-14 01:14

这里需要注意一下,我用Django 1.8的,按照教程会出现TemplateDoesNotExist异常,是因为settings.py文件还有一个地方需要修改路径地址。TEMPLATE里面的DIRS,理论上填上os.path.join(BASE_DIR, 'templates')可以了(和最下面的TEMPLATE_DIRS一样。)

qwe 01-14 06:22

一样的步骤下来却还是出错说找不到资源,为什么 Template-loader postmortem Django tried loading these templates, in this order: Using engine django: django.template.loaders.filesystem.Loader: /home/bytetech/mysite/templates/current_datetime (Source does not exist) django.template.loaders.app_directories.Loader: /usr/lib/python2.7/site-packages/Django-1.9.1-py2.7.egg/django/contrib/admin/templates/current_datetime (Source does not exist) django.template.loaders.app_directories.Loader: /usr/lib/python2.7/site-packages/Django-1.9.1-py2.7.egg/django/contrib/auth/templates/current_datetime (Source does not exist)

对这一段的评论会显示在这里

render_to_response()

对这一段的评论会显示在这里

我们已经告诉你如何载入一个模板文件,然后用 Context渲染它,最后返回这个处理好的HttpResponse对象给用户。 我们已经优化了方案,使用 get_template() 方法代替繁杂的用代码来处理模板及其路径的工作。 但这仍然需要一定量的时间来敲出这些简化的代码。 这是一个普遍存在的重复苦力劳动。Django为此提供了一个捷径,让你一次性地载入某个模板文件,渲染它,然后将此作为 HttpResponse返回。

候鸟 08-11 04:22

还有一个方法叫render比render_to_response更短,一般用那个

boban 09-15 04:42

在原文里,这个函数变成 render()

迷途小前端 12-11 06:47

render是render_to_response的升级版

kunnka wong 05-31 06:56

return render(request,'current_datetime.html',locals()) 这个的确更简洁

对这一段的评论会显示在这里

该捷径就是位于 django.shortcuts 模块中名为 render_to_response() 的函数。大多数情况下,你会使用](#id19)`\ ```[``对象,除非你的老板以代码行数来衡量你的工作。

对这一段的评论会显示在这里

Inline literal start-string without end-string.

对这一段的评论会显示在这里

Inline literal start-string without end-string.

对这一段的评论会显示在这里

Inline literal start-string without end-string.

08-27 12:50

大多数情况下,你会使用render_to_response()而不是手动加载模板并创建Context和HttpResponse对象,除非你的老板以代码行数来衡量你的工作

huangzj 06-13 08:55

网页上面的那些冒号很让人费解

ljifanyi 11-18 17:52

翻译的太TM垃圾了!

peng 01-15 21:14

to ljifanyi: 翻译的垃圾你来翻啊?!垃圾你还看?看原著去。最讨厌你这种人了,什么都不干光说讨厌的话!

ivy 04-17 02:02

有什没错误指出来,或者你自己翻译,别人辛苦的工作,免费给你看,你却嫌弃!抵制蠢货!

chris 06-16 04:04

罵垃圾的,去看原文吧,本事不夠就別在這亂

fly fish 07-24 02:05

@ljifanyi 你TM脑子有问题?!

atlas 09-13 09:04

@ljifanyi 请你尊重人家,闲人家不行的话,要不你来?

lgy 11-10 12:40

翻译的挺不错的。不知道为什么有人乱喷

作为入门篇,非常好,谢谢开源贡献 12-04 09:42

tiant167 01-14 11:20

谢谢 @光

starof 03-19 08:05

翻译的确实有时让人费解,还好我们可以通过评论交流,评论帮了我大忙

chiedey 04-12 12:53

素质素质...

learn 05-14 07:17

有看的就不错了,真不知道骂人的是什么心态

匿名读者 05-22 07:27

有个中文的确实很棒啊

NigelYang 11-05 09:34

我觉得是这样的:翻译呢自然是问题一大堆,而且我看很多反馈了很久都没有得到修改的。但是博主是画了大量时间、精力和金钱来做这件事的,而且是无偿给大家阅读,就凭这你就不能随意骂别人的成果是垃圾。

爱秋风 12-26 01:11

你会使用``\ ``````对象 这个是啥意思啊......

gyyzyp 01-18 05:35

一个人无偿做这样一个工作来使得我们获益 本就很好了 而且 翻译这么多内容 肯定不免有一些纰漏 这些纰漏也通过我们大家的沟通得到了解决 能更加深我们的理解和印象 希望不喜勿喷

pizzabad 06-22 12:52

为啥网页显示 System Message: WARNING/2 (<string>, line 1736); backlink Inline literal start-string without end-string. System Message: WARNING/2 (<string>, line 1736); backlink Inline literal start-string without end-string. System Message: WARNING/2 (<string>, line 1736); backlink Inline literal start-string without end-string.

JulyClyde 07-20 04:38

免费就是不好好干的借口么?先不说把阅读者吸引过来结果没学成,浪费了阅读者的时间;单说就这种质量,对得起自己花费的时间吗?对得起社区的名声吗?

mingming 11-23 04:26

“免费就是不好好干的借口么?”这么浩大无私的翻译工程,你有什么资格一句话说就能说别人不好好干,一句话否定别人这么无私的奉献?你是出资人还是那根葱?就问一句你有什么资格?“先不说把阅读者吸引过来结果没学成,浪费了阅读者的时间;单说就这种质量,对得起自己花费的时间吗?对得起社区的名声吗?”别让你的自私自利污染了所有阅读者,你只是代表你,“没学成,浪费时间”一说也只是代表你自己,没人逼着你“浪费时间”。要是真的评判责任,那也只是你自己对自己负责。另外,社区的名声也不是你能否定的,这么多读者的热情支持也不是你一句话能否定的。不想说什么,自己学会对自己负责,没人能替你。

aaron 05-04 09:22

这么好的资源,网页连广告都没有,不知道某些喷子还有什么不满意的,作者也可以做,也可以不做,人家做了,给大家这么好的学习机会 还有什么不满足的 不要每天只是喷喷喷

这个评论的插件非常棒 08-31 08:12

这个评论的插件非常棒,请问博主可稍稍说一下是什么插件呀

xiaopanddxiong 08-03 09:23

看到大家都在骂这傻逼 我也就放心了

shine 05-25 08:32

包容点

对这一段的评论会显示在这里

下面就是使用 render_to_response() 重新编写过的 current_datetime 范例。

对这一段的评论会显示在这里
from django.shortcuts import render_to_response
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    return render_to_response('current_datetime.html', {'current_date': now})
goofy 09-10 10:05

有什么技巧区分a=f(args)这种形式是把一个函数的返回值付给a变量还是实例化一个f类型的对象个a变量

goofy 09-10 10:06

有什么技巧区分a=f(args)这种形式是把一个函数的返回值付给a变量还是实例化一个f类型的对象给a变量

ode2free 04-08 09:52

不会区分。求教。

snyh 05-13 08:13

to goofy: 这两者应该是一样的. 实例化一个class 不就是调用class的构造方法来生成一个object作为返回值 i = int("3") i = myself_to_int("3") 这两种本质应该是一样的, 只是前者有语法糖(i = int("3")) 等同于(只是猜想,对于python也是刚接触) result = {} int.__init__(result, "3") return result 如果非要区分的话就要看f(args) 中的f是什么东西了 是函数就是函数调用, 是类名就是实例化 通过 f.__class__的内容或者通过hasattr来检测是否有f.__init__这个方法 具体情况具体看待吧

carlcarl 04-06 18:24

我會考慮將class的名稱開頭設為大寫,跟 method分開來,這樣就能區分了。

匿名读者 07-27 13:56

通常情况下,类名大写,函数名小写

kevinkelin 02-21 15:21

current_date 应该为 current_time

kevinkelin 02-21 15:26

"current_date 应该为 current_time" 我看错了,就是current_date, 上面的html中已经为current_date

Pusugar 04-18 09:43

同步实践时应注意:将current_datetime.html中的{{current_date}}改为{{current_datetime}}。文中前后不一致。

chris 06-16 07:21

原文的做法是 return render(request, 'dateapp/current_datetime.html', {'current_date': now}) 同樣也可,不知哪種做法較好?

Andy 09-16 06:36

return render(request, 'current_datetime.html', {'current_date': now}) 这样写也可以

zhufree 10-18 04:04

为毛我各种改了之后显示的网页还是原来那样,不显示错误,也没有改进呢?包括我把views.py删掉以后还能正常显示,这是怎么回事!

agon 10-19 08:05

from django.shortcuts import render \n<br /> return render(request, 'current_datetime.html', {'current_date': now})现在这样写

加菲猫 02-08 08:11

英文版现在用的是render 不是render_to_response. 有什么区别呢? 哪个更好?

加菲猫 02-08 08:13

render render_to_response的区别.参见连接

匿名读者 05-22 07:39

http://www.douban.com/note/278152737/ http://stackoverflow.com/questions/5154358/django-what-is-the-difference-between-render-render-to-response-and-direc

Tommy 07-10 01:34

貌似还有一个render方法实现同样的功能。(django:1.6.5)

Xavier 07-15 06:27

用render,这个过时了,render大法好

Yinz 12-10 16:19

注意改为rander的话应该修改import 为from django.shortcuts import render ,否则会出现NameError

Yinz 12-10 16:20

手误,rander→render

匿名读者 03-11 14:03

render(request, 'current_datetime.html',{"current_datetime":now})

skip 08-30 05:14

render() Required arguments 是 request 和 template_name 有两个,而render_to_response() Required arguments 只有一个是 template_name,后者更少写起来不是更方便吗?

Jaya 11-20 07:04

新版使用render即可. from django.shortcuts import render import datetime def current_datetime(request): now = datetime.datetime.now() return render(request, 'current_datetime.html', {'current_date': now})

流沙 11-13 09:49

现在的Django版本已经将 render_to_response()变为render()了,网上有很多这两者之间的介绍文章

流沙 11-13 09:50

现在的Python版本已经将 render_to_response()变为render()了,网上有很多这两者之间的介绍文章

Memory 03-31 02:26

直接return render(request, 'current_datetime.html', {'current_date': now}) 就行啦(Django2.1.7测试有效)

老刘 07-20 09:26

TemplateResponse

老刘 07-20 09:29

def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context)

对这一段的评论会显示在这里

大变样了! 让我们逐句看看代码发生的变化:

对这一段的评论会显示在这里
  • 我们不再需要导入 get_templateTemplateContextHttpResponse 。相反,我们导入 django.shortcuts.render_to_responseimport datetime 继续保留.
  • current_datetime 函数中,我们仍然进行 now 计算,但模板加载、上下文创建、模板解析和 HttpResponse 创建工作均在对 render_to_response() 的调用中完成了。 由于 render_to_response() 返回 HttpResponse 对象,因此我们仅需在视图中 return 该值。
对这一段的评论会显示在这里

render_to_response() 的第一个参数必须是要使用的模板名称。 如果要给定第二个参数,那么该参数必须是为该模板创建 Context 时所使用的字典。 如果不提供第二个参数, render_to_response() 使用一个空字典。

谢营长 06-17 09:29

这个函数堪称伟大啊

tony 07-13 09:06

总算知道为什么django可以实现快速开发了。

lincy 08-13 11:23

我也来赞一下这个函数

atlas 09-13 09:15

这函数太给力了,代码简短大半啊

lgy 11-10 12:48

COOL

hjz 01-25 07:39

原文用的是render()函数而非render_to_response(),作用应该差不多

alan 03-03 14:11

这个函数太爽了!

william 04-24 10:10

看到这里终于忍不住要赞叹一下Django了,真是太简洁了。

learn 05-14 07:21

还行吧,不至于,自己也可以封装一下调用

mihello 08-02 16:16

英文版更新到Django 1.4, 1.5 用render()函数 http://www.djangobook.com/en/2.0/chapter04.html

mihello 08-02 16:16

其实Flask的render_template 函数也是一样

Adam Xu 09-22 07:56

good

11 09-29 11:26

这个函数太给力了

misutt 10-18 10:51

给力啊~

FRANK 02-08 14:27

render_to_response()函数下岗了,进化为render(request,'templatename',Context)函数!一句话解决问题!!!

mr.liu 06-01 09:55

强大强大!必须学习!

猪头哥哥 11-30 05:23

django1.11版本里可以用render() from django.shortcuts import render # # return render(request,'template名字',{'current_date':str(now)}) request不可以缺 context接收字典

lee 12-04 09:33

哈哈哈,程序猿偷懒就能进步哈,把重复繁琐的过程抽取到函数中,随用随调

Ignora 01-24 10:42

render函数做了什么改进?仅仅是函数名变短了一些吗?

对这一段的评论会显示在这里

locals() 技巧

stranger 05-31 02:35

有点难理解。

antidote 09-10 07:49

还好,看懂了。。 locals() 这个很少用。。。 很少这样偷懒

CcChen 03-21 00:25

使用locals()会不会存在一些安全隐患?

ok 05-06 09:12

在这章的签名模板基础语法哪里,什么字典什么[]哪里有点模糊,不知道什么时候使用......

python 08-05 06:12

用了Locals() 会不会对性能影响过大

候鸟 08-11 04:18

用locals不是好习惯,如果本地变量过多会造成你以后修改代码不知道模板中用了变量,如果变量过少也自然没有必要用locals,想来想去使用场景可能只有当view方法是一个动态方法时候

firewall 04-04 07:43

如果这样改了locals(),没有做其它修改的话就出错了。不说详细不利于新手。

匿名读者 07-31 13:43

loca()前面的变量要和模板匹配

mihello 08-02 16:18

英文版更新至Django 1.4 没有介绍locals可能不用了

吴某人 04-03 09:47

表示我个人不太喜欢这个local()。因为我是那种「如果每一个自己设定的变量在使用时没有被调用或者被调用了却没有显示在哪里调用就会重新写程序」的人

对这一段的评论会显示在这里

思考一下我们对 current_datetime 的最后一次赋值:

对这一段的评论会显示在这里
def current_datetime(request):
    now = datetime.datetime.now()
    return render_to_response('current_datetime.html', {'current_date': now})
对这一段的评论会显示在这里

很多时候,就像在这个范例中那样,你发现自己一直在计算某个变量,保存结果到变量中(比如前面代码中的 now ),然后将这些变量发送给模板。 尤其喜欢偷懒的程序员应该注意到了,不断地为临时变量临时模板命名有那么一点点多余。 不仅多余,而且需要额外的输入。

666 12-14 08:37

一直在计算 now 如果 current_datetime 被多次调用的话

潮湿了我押韵的心情 12-14 08:38

一直在计算 now 如果 current_datetime 被多次调用的话

对这一段的评论会显示在这里

如果你是个喜欢偷懒的程序员并想让代码看起来更加简明,可以利用 Python 的内建函数 locals() 。它返回的字典对所有局部变量的名称与值进行映射。 因此,前面的视图可以重写成下面这个样子:

ani_di 04-20 07:40

locals很好用

lu4nx 05-27 14:07

看场合了。。。有些时候locals()反而更是个负担

louis 09-19 08:19

由上文所说,写模板和python代码的往往不是同一个人,那么后期很多变量的名字又需要检查然后统一起来,再进行整合?

Solaris 01-28 08:28

这看起来非常棒!

没钱没闲 03-29 06:51

在这里的时候,用locals要写一下对应的在html里面的读取方式,不然这么写是错误的。我是完全的新手,只会按照例子一步一步来。如果替换了这段代码,那么实际上运行起来就是错误的。

HankZ 05-30 08:16

绝币帅气!!!!逆天了这个

dengj 06-05 14:15

如果在后台变量很多的情况下,性能还是很好地话!我靠!赞!

TTTsand 09-15 08:02

添加locals()函数后显示的是一个字典?为啥

hehe 12-16 16:21

尼玛,为什么我后面加了个#参数:文件名。。。一个注释啊啊啊啊啊,都报错。。。pydev这么挫吗

QQasdhy 05-05 12:17

locals()的返回值是一个包含此函数执行到该时间点所定义的所有变量的字典。

aaron 05-04 09:52

@没钱没闲 用locals要写一下对应的在html里面的读取方式 请问在哪里怎么写html对应的读取方式呢?

afk 10-30 09:43

现在很多教程已经没有看见使用local函数的了,估计开发者也是不推荐使用的

安铺靓仔 07-19 13:23

locals 和globals 不建议使用,不然后期维护困难

对这一段的评论会显示在这里
def current_datetime(request):
    current_date = datetime.datetime.now()
    return render_to_response('current_datetime.html', locals())
对这一段的评论会显示在这里

在此,我们没有像之前那样手工指定 context 字典,而是传入了 locals() 的值,它囊括了函数执行到该时间点时所定义的一切变量。 因此,我们将 now 变量重命名为 current_date ,因为那才是模板所预期的变量名称。 在本例中, locals() 并没有带来多 的改进,但是如果有多个模板变量要界定而你又想偷懒,这种技术可以减少一些键盘输入。

keyman 10-24 05:37

lcoals() 我的理解是,根据模板里面的定义变量名,

keyman 10-24 05:38

locals() 我的理解是,根据模板里面的定义变量名,

keyman 10-24 05:43

views.py: from django.shortcuts import render_to_response import datetime def current_datetime(request): now1 = datetime.datetime.now() system="keyman.example.com" return render_to_response('index.html',locals()) index.html: <html> <body> <h1> {{system}}'s time is now {{now1}}.</h1> </body> </html>

小峰 12-20 07:25

变量值是中文的话会报错,咋办?

zjnjxufe 01-25 06:40

个人觉得locals应该蛮好用的,只不过在模板里的变量的名字要和你在views中定义的一样,这样在你用render_to_response时,就不会要在末尾写一长串的数据了

zenpython 02-08 14:26

locals()太牛了。

谢营长 06-17 09:34

如果有多个局部变量怎么区分呢

locals()应该是返回给每一个局部变量添加一个同名键值的字典吧,这样就必须保证模块里面的变量名字 08-08 18:25

lincy 08-13 11:32

敢问楼上是怎么把评论弄成这样的

lincy 08-13 11:38

这里并没有违背模板和代码分离,因为即使你不用locals(),你也要写 {'current_date': now},这里的current_date也要和模板里的变量名匹配

misugi 08-14 10:02

同意楼上的观点

atlas 09-13 09:45

代码越来越简短啊,呵呵

kamushin 09-30 15:49

locals()是Python中自带的

矮玛尔 11-07 08:52

对于n多变量这个应该非常好使,而且省事,对于少量变量可能效率不会太高吧,因为locals()本身还包括很多其他变量 还有一点就是 locals()只能用于1对1吧 如果多对一的情况 就不好办 不知道实际中有么有这种情况 对于一对多我想应该是不会 有对吧^ ^

@lincy 我有特殊的输入技巧,其实你楼上输入的是‘名字’ 04-24 17:06

@lincy

Xavier 07-15 06:36

英文版里面这段关于locals()的去掉了! 还是别用了

匿名读者 11-13 13:13

太暴力了

不满 06-16 09:26

个人不建议这么搞,意义不大

wangyue 10-10 02:28

写代码最好要让人直接看懂,而不是二次理解,花时间去弄清楚你表达的意思。 ```# 比如使用工厂函数 d = dict( name='wang', sale='man', ) render_to_response('current_datetime.html', d) ```

lee 12-04 09:36

<b>不值得,为了这点单词,牺牲可读性</b>

泥奏凯 10-23 14:36

如果存在多个名字相同的局部变量的时候,locals是可以区分的么?

电饭锅 02-05 07:55

#FFC0CB 确实是个鸡肋的方法,不过对于不需要太多参数的模板来说还是很好用的

橙子 10-13 09:09

使用locals()没法传参耶。。

橙子 10-13 10:38

使用locals()没法传参耶。。--》错因找到了,因为变量没有匹配上。。--》 如果要使用locals(),就要保证 视图层函数里 定义的变量名与模板里相应的变量名一致,才能成功传参。 如果用视图层用字典传参,则不要求名字一致。

对这一段的评论会显示在这里

使用 locals() 时要注意是它将包括 所有 的局部变量,它们可能比你想让模板访问的要多。 在前例中, locals() 还包含了 request 。对此如何取舍取决你的应用程序。

对这一段的评论会显示在这里

get_template()中使用子目录

对这一段的评论会显示在这里

把所有的模板都存放在一个目录下可能会让事情变得难以掌控。 你可能会考虑把模板存放在你模板目录的子目录中,这非常好。 事实上,我们推荐这样做;一些Django的高级特性(例如将在第十一章讲到的通用视图系统)的缺省约定就是期望使用这种模板布局。

py 05-10 02:13

对这一段的评论会显示在这里

把模板存放于模板目录的子目录中是件很轻松的事情。 只需在调用 get_template() 时,把子目录名和一条斜杠添加到模板名称之前,如:

对这一段的评论会显示在这里
t = get_template('dateapp/current_datetime.html')
对这一段的评论会显示在这里

由于 render_to_response() 只是对 get_template() 的简单封装, 你可以对 render_to_response() 的第一个参数做相同处理。

对这一段的评论会显示在这里
return render_to_response('dateapp/current_datetime.html', {'current_date': now})
潮湿了我押韵的心情 12-14 09:03

mark

对这一段的评论会显示在这里

对子目录树的深度没有限制,你想要多少层都可以。 只要你喜欢,用多少层的子目录都无所谓。

对这一段的评论会显示在这里

注意

对这一段的评论会显示在这里

Windows用户必须使用斜杠而不是反斜杠。 get_template() 假定的是 Unix 风格的文件名符号约定。

leisurem 12-18 09:06

windows下,斜杠,反斜杠都可以哦 写成这样都可以: return render_to_response('dateapp\current_datetime.html', {'dateapp/current_date': now,'happy':565135,'happy':'hahaha'})

qq345421243 05-09 06:34

经过测试,同意楼上的,python版本是2.7.3

jojo 03-19 10:11

无名小卒 11-08 09:29

leisurem 说的对,windows两种斜杠都可以

Narcissist1 12-17 12:56

多谢

阿卓 10-19 01:28

render_to_response()在新版的django中被更简洁的render()所替代,可以参考django的官方网站。

对这一段的评论会显示在这里

include 模板标签

对这一段的评论会显示在这里

在讲解了模板加载机制之后,我们再介绍一个利用该机制的内建模板标签: {% include %} 。该标签允许在(模板中)包含其它的模板的内容。 标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引号硬编码的字符串。 每当在多个模板中出现相同的代码时,就应该考虑是否要使用 {% include %} 来减少重复。

对这一段的评论会显示在这里

下面这两个例子都包含了 nav.html 模板。这两个例子是等价的,它们证明单/双引号都是允许的。

对这一段的评论会显示在这里
{% include 'nav.html' %}
{% include "nav.html" %}
huangzj 06-13 09:07

我觉得最好规范一下,如果只允许单引号或者只允许双引号,程序员要记的东西就少了很多,也不至于混淆了

xing.lin 08-19 08:23

单引号和双引号在本质上没有区别,个人还倾向于单引号

peer.xu 12-31 03:27

这里描述的是django允许这样做,但是规范定义的话是落实到具体的项目中的编码规范.

Sheriaty 01-23 04:35

python 语法中貌似对于单引号双引号没明确区分。。何必纠结这种小问题。。。

dkjiaoyang 04-10 00:07

其实我就是想知道下,这两种在这里有没有什么本质区别?

byrain 07-19 08:13

没有本质不同吧

lincy 08-13 11:42

二者没有什么本质的区别,python都支持。但是如果字符串内部有引号时,外部应用双引号,如:"hellow, 'world'."

atlas 09-13 10:05

@lincy 说的正确

对这一段的评论会显示在这里

下面的例子包含了 includes/nav.html 模板的内容:

对这一段的评论会显示在这里
{% include 'includes/nav.html' %}
潮湿了我押韵的心情 12-14 09:11

使用存放于模板目录的子目录中的nav.html模板

对这一段的评论会显示在这里

下面的例子包含了以变量 template_name 的值为名称的模板内容:

对这一段的评论会显示在这里
{% include template_name %}
atlas 09-13 12:13

这里是什么意思呢,不明白

cqf 02-10 12:31

这里应该是说相当于可以用变量来引用模版。例如,template_name 可以是nav.html。

潮湿了我押韵的心情 12-14 09:16

也就是调用在模板目录里名为 template_name 的模板;换句话说,模板目录里的模板文件的文件名,就是一些变量, 调用这些变量,也就是这些模板

潮湿了我押韵的心情 12-14 09:17

也就是调用在模板目录里名为 template_name 的模板;换句话说,模板目录里的模板文件的文件名,就是一些变量, 调用这些变量,也就是调用这些模板

Ignora 01-24 10:56

楼上试过吗张口就来?变量template_name是指一个字符串变量,此句之前需要对其赋值,存放一个文件名。

对这一段的评论会显示在这里

和在 get_template() 中一样, 对模板的文件名进行判断时会在所调取的模板名称之前加上来自 TEMPLATE_DIRS 的模板目录。

对这一段的评论会显示在这里

所包含的模板执行时的 context 和包含它们的模板是一样的。 举例说,考虑下面两个模板文件:

对这一段的评论会显示在这里
# mypage.html

<html>
<body>
{% include "includes/nav.html" %}
<h1>{{ title }}</h1>
</body>
</html>

# includes/nav.html

<div id="nav">
    You are in: {{ current_section }}
</div>
simin 06-09 07:26

此处“注释”的语法好像不对吧,模板中的注释不应该在末尾再加上一个“#”么?

simin 06-09 07:27

好吧,看错了,这里写的不是单独的模板文件。。。

猪头哥哥 11-30 05:55

这是两个文件

对这一段的评论会显示在这里

如果你用一个包含 current_section的上下文去渲染 mypage.html这个模板文件,这个变量将存在于它所包含(include)的模板里,就像你想象的那样。

sapjax 07-20 10:12

这个貌似和php的include不一样,include进来的只是模板,每次include后都需要重新传入context,麻烦了很多 不过一个好处是,模板的重用性变高了

jude 09-03 13:55

“这个变量将存在于它所包含的模板里”,这句话的原文:then the variable will be available in the “included” template。觉得可以翻译成:那么就可以在它所包含的模板里使用这个变量(current_section)。

迷途小前端 12-11 06:54

LS还是个文学家 >_<

sy 05-15 02:52

为什么我显示不出来current_section 的内容呢

对这一段的评论会显示在这里

如果{% include %}标签指定的模板没找到,Django将会在下面两个处理方法中选择一个:

卿云 01-08 18:11

如错写若

对这一段的评论会显示在这里
  • 如果 DEBUG 设置为 True ,你将会在 Django 错误信息页面看到 TemplateDoesNotExist 异常。
  • 如果 DEBUG 设置为 False ,该标签不会引发错误信息,在标签位置不显示任何东西。
mark 06-30 15:54

对这一段的评论会显示在这里

模板继承

候鸟 08-11 04:25

继承和include区别用一句话概括就是,继承解决不同页面的重复内容,include解决同一页面内相同内容,相对来说include的使用其实比较少

mr.liu 06-03 02:28

每当在多个模板中出现相同的代码时,就应该考虑是否要使用 {% include %} 来减少重复。

对这一段的评论会显示在这里

到目前为止,我们的模板范例都只是些零星的 HTML 片段,但在实际应用中,你将用 Django 模板系统来创建整个 HTML 页面。 这就带来一个常见的 Web 开发问题: 在整个网站中,如何减少共用页面区域(比如站点导航)所引起的重复和冗余代码?

对这一段的评论会显示在这里

解决该问题的传统做法是使用 服务器端的 includes ,你可以在 HTML 页面中使用该指令将一个网页嵌入到另一个中。 事实上, Django 通过刚才讲述的 {% include %} 支持了这种方法。 但是用 Django 解决此类问题的首选方法是使用更加优雅的策略—— 模板继承

Gitree 08-14 16:08

解决该问题的传统做法是使用 服务器端的 include,

对这一段的评论会显示在这里

本质上来说,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载。

对这一段的评论会显示在这里

让我们通过修改 current_datetime.html 文件,为 current_datetime 创建一个更加完整的模板来体会一下这种做法:

对这一段的评论会显示在这里
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>The current time</title>
</head>
<body>
    <h1>My helpful timestamp site</h1>
    <p>It is now {{ current_date }}.</p>

    <hr>
    <p>Thanks for visiting my site.</p>
</body>
</html>
limitless 10-10 08:47

<p>It is now {{current_datetime}}.</p> 吧

<p>It is now {{ current_date }}.</p> 03-04 08:10

linkin 04-22 12:31

1.9的版本中,unicode的解码错误,在这里修改第一句为<!DOCTYPE HTML5>即可

kunnka wong 05-31 08:10

回答1楼, 这个作者的写法是没错的,之前定义的变量名字就是这个

kunnka wong 05-31 08:11

之前是这样返回给模板的 return render_to_response('current_datetime.html',{'current_date':now})

对这一段的评论会显示在这里

这看起来很棒,但如果我们要为第三章的 hours_ahead 视图创建另一个模板会发生什么事情呢?

对这一段的评论会显示在这里
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>Future time</title>
</head>
<body>
    <h1>My helpful timestamp site</h1>
    <p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>

    <hr>
    <p>Thanks for visiting my site.</p>
</body>
</html>
潮湿了我押韵的心情 12-14 10:27

<p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p> 其他地方不变

对这一段的评论会显示在这里

很明显,我们刚才重复了大量的 HTML 代码。 想象一下,如果有一个更典型的网站,它有导航条、样式表,可能还有一些 JavaScript 代码,事情必将以向每个模板填充各种冗余的 HTML 而告终。

对这一段的评论会显示在这里

解决这个问题的服务器端 include 方案是找出两个模板中的共同部分,将其保存为不同的模板片段,然后在每个模板中进行 include。 也许你会把模板头部的一些代码保存为 header.html 文件:

对这一段的评论会显示在这里
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
对这一段的评论会显示在这里

你可能会把底部保存到文件 footer.html :

对这一段的评论会显示在这里
    <hr>
    <p>Thanks for visiting my site.</p>
</body>
</html>
对这一段的评论会显示在这里

对基于 include 的策略,头部和底部的包含很简单。 麻烦的是中间部分。 在此范例中,每个页面都有一个 <h1>My helpful timestamp site</h1> 标题,但是这个标题不能放在 header.html 中,因为每个页面的 <title> 是不同的。 如果我们将 <h1> 包含在头部,我们就不得不包含 <title> ,但这样又不允许在每个页面对它进行定制。 何去何从呢?

对这一段的评论会显示在这里

Django 的模板继承系统解决了这些问题。 你可以将其视为服务器端 include 的逆向思维版本。 你可以对那些 不同 的代码段进行定义,而不是 共同 代码段。

对这一段的评论会显示在这里

第一步是定义 基础模板 , 该框架之后将由 子模板 所继承。 以下是我们目前所讲述范例的基础模板:

GerogeChen 03-28 09:30

能这么用真是太好了!!!! 兴奋了。

ok 05-06 09:22

我也觉得很兴奋呀。不过她跟php还有点像呀

louis 09-19 08:47

的确能省去好多冗余和重复敲代码的工作。

cc 03-18 12:48

my godness!

ting 04-18 06:20

感觉就像是web.py的模版和tornado的模版,web.py是用include,tornado是用继承

df 10-08 05:55

基础模板 不能使用变量么?

cqf 02-10 14:04

这里的{% block footer %}和下面的{% endblock %}的作用是什么,感觉是可以去掉的

cqf 02-10 14:06

好吧,下面有说清楚 - -

吴某人 04-03 11:11

没这个继承还真的是很难写网页啊

lyz 12-24 14:26

很实用!

对这一段的评论会显示在这里
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <h1>My helpful timestamp site</h1>
    {% block content %}{% endblock %}
    {% block footer %}
    <hr>
    <p>Thanks for visiting my site.</p>
    {% endblock %}
</body>
</html>
d的 09-23 08:55

chaos 08-03 06:32

{% block footer %}{%endblock%}标签中的内容会一直现实吗,如果子类继承的的,两者的内容不会冲突吗?怎么显示啊

对这一段的评论会显示在这里

这个叫做 base.html 的模板定义了一个简单的 HTML 框架文档,我们将在本站点的所有页面中使用。 子模板的作用就是重载、添加或保留那些块的内容。 (如果你一直按顺序学习到这里,保存这个文件到你的template目录下,命名为 base.html .)

huangzj 06-13 09:16

应该是templates目录,少了个s

君不见 04-14 02:59

对,如果一直读下来,是templates目录 忘修正

君不见 04-14 02:59

对,如果一直读下来,是templates目录 望修正

ivandai 09-11 03:12

文件位置一定要注意,否则会报错。

对这一段的评论会显示在这里

我们使用一个以前已经见过的模板标签: {% block %} 。 所有的 {% block %} 标签告诉模板引擎,子模板可以重载这些部分。 每个{% block %}标签所要做的是告诉模板引擎,该模板下的这一块内容将有可能被子模板覆盖。

朱开全 08-10 14:13

此处应该是:我们使用了一个以前未见到过的模板标签:***

qq345421243 05-09 06:50

block footer这块重复,可以去掉

atlas 09-27 09:33

@qq345421243 你的说法是错误的

我没见过…… 12-24 06:55

lou 06-25 09:12

We’re using a template tag here that you haven’t seen before:

对这一段的评论会显示在这里

现在我们已经有了一个基本模板,我们可以修改 current_datetime.html 模板来 使用它:

wzl 05-22 12:47

{% extends "base.html" %} {% block title %}The current time{% endblock %} 把{% block title %}The current time{% endblock %}中The current time改为中文后报错'utf8' codec can't decode byte 0xc0 in position 48: invalid start byte,其他地方改中文没事

雪落无痕 07-17 06:13

{% extends "你的模板页面"%}必须放在子页面的开头,前面连一个注释行都不可以。

对这一段的评论会显示在这里
{% extends "base.html" %}

{% block title %}The current time{% endblock %}

{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}
hLongQ 05-29 09:48

这个地方把{% block title %}The current time{% endblock %}放在{% block content %}...{% endblock %}后面是没有影响其继承,结果是一样的

fakenerd 07-20 08:54

模板的模板

baichenjia 04-16 12:49

那block footer 呢

zhangsan 08-14 06:33

Invalid template name in 'extends' tag: ''. Got this from the 'base.html' variable

请注意:{% extends ... %}必须放在html第一行! 04-02 07:15

Kog'Maw 04-02 07:16

请注意:{% extends ... %}必须放在html第一行!

对这一段的评论会显示在这里

再为 hours_ahead 视图创建一个模板,看起来是这样的:

对这一段的评论会显示在这里
{% extends "base.html" %}

{% block title %}Future time{% endblock %}

{% block content %}
<p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>
{% endblock %}
looly 01-20 12:10

这里一定要注意,如果模板文件使用utf8编码的话,一定要定义为无BOM的utf8,否则会出现样式混乱的问题。

ddgg 05-23 02:41

hour_offset这块不显示怎么弄?

zhoubo 06-03 15:35

return render_to_response('hours_ahead.html', ({'hour_offset':offset,'next_time':dt}))

wkm 09-14 14:58

# 修改变量名,让locals()对应起来 def hours_ahead(request, hour_offset): try: hour_offset = int(hour_offset) except ValueError: raise Http404() next_time = datetime.datetime.now() + datetime.timedelta(hours=hour_offset) return render_to_response('dateapp/hours_ahead.html', locals())

wkm 09-14 14:59

# 修改变量名,让locals()对应起来 def hours_ahead(request, hour_offset): try: hour_offset = int(hour_offset) except ValueError: raise Http404() next_time = datetime.datetime.now() + datetime.timedelta(hours=hour_offset) return render_to_response('dateapp/hours_ahead.html', locals())

itonla 10-20 15:55

谢谢,@zhoubo和@wkm

小康不起来 12-19 08:35

为什么我的始终报:hours_ahead() takes exactly 2 arguments (1 given)。代码和你们都一样的。

柚子皮 01-22 17:25

应该是urls.py中正则表达式部分你没加括号 (r'^time/plus/(\d{1,2})/$', hours_ahead),

Young 05-11 05:56

我的hour_ahead这个网页能够显示内容,但是base.html 里面的东西却不显示,这是怎么回事?

djuser 06-20 09:42

这个继承功能真心不赖....

bee3134 11-05 07:33

@Young ,同样的疑问

Adoo 12-19 07:05

如果是用LOCALS()函数的话,注意block里面的变量和view.py函数里的变量一致就好了。

匿名读者 12-24 06:57

一点都不漂亮

QQasdhy 05-05 13:16

view里面hours_ahead函数修改变量名为模板需要调用的next_time,然后在render_to_response函数中使用locals(); return render_to_response('hours_ahead.html', locals())

Sean 04-24 14:55

文章中没有给出具体实现步骤,本来我只能打开/time/这个部分,/plus/部分的显示模版不存在,我参考了楼上的部分代码,具体操作如下: 在templates文件夹里分别新建base.html和hours_ahead.html两个文件,并把相应代码写进去,之后需要修改一下views.py里的hours_ahead函数,代码如下: def hours_ahead(request, hour_offset): try: hour_offset = int(hour_offset) except ValueError: raise Http404() next_time = datetime.datetime.now() + datetime.timedelta(hours=hour_offset) return render_to_response('hours_ahead.html', locals())

猪头哥哥 11-30 06:12

在这里用locals()就能明显看出来优势,但是locals()也不能乱用 return render(request,'hours_ahead.html',{'hour_offset':hour_offset,'next_time':next_time})=== return render(request,'hours_ahead.html',locals())

匿名读者 04-23 10:28

Django2.2 按照楼上Sean的做法是可行的

对这一段的评论会显示在这里

看起来很漂亮是不是? 每个模板只包含对自己而言 独一无二 的代码。 无需多余的部分。 如果想进行站点级的设计修改,仅需修改 base.html ,所有其它模板会立即反映出所作修改。

grunmin 03-04 09:18

这样的话感觉高耦合了,修改了base模板(比如增减某个标签)就需要修改所有的子模板。不知道是不是这样?

psd 05-25 02:13

回复ls:程序员应当只有认为需要的改动应该在所有继承自该模板的子模版中都表现出来时才会去直接改base模板,否则不是自找苦吃嘛。退一步讲,如果对于大多数自模版,要修改的内容是一样的,那就直接写在base模板中,然后只需要在那些少数不一样的子模板中覆盖一下就行了

猪头哥哥 11-30 06:16

并没有高耦合吧,如果对于某个特定的页面改动 可以单独拎出来改

对这一段的评论会显示在这里

以下是其工作方式。 在加载 current_datetime.html 模板时,模板引擎发现了 {% extends %} 标签, 注意到该模板是一个子模板。 模板引擎立即装载其父模板,即本例中的 base.html

对这一段的评论会显示在这里

此时,模板引擎注意到 base.html 中的三个 {% block %} 标签,并用子模板的内容替换这些 block 。因此,引擎将会使用我们在 { block title %} 中定义的标题,对 {% block content %} 也是如此。 所以,网页标题一块将由 {% block title %}替换,同样地,网页的内容一块将由 {% block content %}替换。

57 05-06 09:08

{ block title %} -> {% block title %}

Woods 10-23 09:03

可以继承多个模板吗?

yw 07-10 06:52

{% block content %} <table> <colgroup> <col class="col1"> <col class="col2"> {% block tbody %}{% endblock %} </table> {% endblock %} 可以嵌套吗? 这样写可以吗?

sapjax 07-20 10:37

@yw 嵌套的话,逻辑上不对啊,block content已经是可变的了,block tbody放在base中哪里呢?

Ura 01-05 14:14

这里对模板继承写得太笼统了,一点都不详细。。。而且逻辑有点搞不清。。

dss 01-09 12:31

钩子越多越好? 覆膜板不是只能有意个block content吗?

zjnjxufe 01-25 06:58

其实这个模板继承很好用的,我开发所采用的flask框架的模板继承和这个是一样的。block里面可以嵌套block,但如果没有别的模板来继承你这个模板,你在该模板的block里面嵌套一个block就没任何意思了

ting 04-18 06:36

tornado的模版也是这样继承的

tuweizhong 10-04 02:24

{% extends "base.html" %} {% block title %}Future Time{% endblock %} {% extends "foot.html" %} <ExtendsNode: extends "foot.html"> must be the first tag in the template. 我改成下面这样 {% extends "base.html" %} {% extends "foot.html" %} {% block title %}Future Time{% endblock %} 'extends' cannot appear more than once in the same template 不可以继承多个的,不过也没必要啊

mr.liu 06-03 03:23

block footer 去哪里了?

对这一段的评论会显示在这里

注意由于子模板并没有定义 footer 块,模板系统将使用在父模板中定义的值。 父模板 {% block %} 标签中的内容总是被当作一条退路。

walkmiao 01-17 12:13

也就是说如果子模板没有对block块作定义的话 将使用父模板的block定义,并不是没有

对这一段的评论会显示在这里

继承并不会影响到模板的上下文。 换句话说,任何处在继承树上的模板都可以访问到你传到模板中的每一个模板变量。

潮湿了我押韵的心情 12-14 12:05

意思就是:父模板乃至 子模板 中的变量都可以被访问,也就都可以被赋值到。

对这一段的评论会显示在这里

你可以根据需要使用任意多的继承次数。 使用继承的一种常见方式是下面的三层法:

对这一段的评论会显示在这里
  1. 创建 base.html 模板,在其中定义站点的主要外观感受。 这些都是不常修改甚至从不修改的部分。
  2. 为网站的每个区域创建 base_SECTION.html 模板(例如, base_photos.htmlbase_forum.html )。这些模板对 base.html 进行拓展,并包含区域特定的风格与设计。
  3. 为每种类型的页面创建独立的模板,例如论坛页面或者图片库。 这些模板拓展相应的区域模板。
adai 08-15 02:00

这个特别要注意下

猪头哥哥 11-30 06:26

这个感觉最关键了

对这一段的评论会显示在这里

这个方法可最大限度地重用代码,并使得向公共区域(如区域级的导航)添加内容成为一件轻松的工作。

对这一段的评论会显示在这里

以下是使用模板继承的一些诀窍:

对这一段的评论会显示在这里
  • 如果在模板中使用 {% extends %} ,必须保证其为模板中的第一个模板标记。 否则,模板继承将不起作用。
  • 一般来说,基础模板中的 {% block %} 标签越多越好。 记住,子模板不必定义父模板中所有的代码块,因此你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。 俗话说,钩子越多越好。
  • 如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个 {% block %} 中。
  • 如果你需要访问父模板中的块的内容,使用 {{ block.super }}这个标签吧,这一个魔法变量将会表现出父模板中的内容。 如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。
  • 不允许在同一个模板中定义多个同名的 {% block %} 。 存在这样的限制是因为block 标签的工作方式是双向的。 也就是说,block 标签不仅挖了一个要填的坑,也定义了在模板中这个坑所填充的内容。如果模板中出现了两个相同名称的 {% block %} 标签,父模板将无从得知要使用哪个块的内容。
  • {% extends %} 对所传入模板名称使用的加载方法和 get_template() 相同。 也就是说,会将模板名称被添加到 TEMPLATE_DIRS 设置之后。
  • 多数情况下, {% extends %} 的参数应该是字符串,但是如果直到运行时方能确定父模板名,这个参数也可以是个变量。 这使得你能够实现一些很酷的动态功能。
Labi Kyo 10-23 11:40

会将模板名称被添加到 -> 是否多了一个"被"字

Woods 10-23 09:06

关于{% extend %}的参数是变量,可以举个例子吗?

pengyao 10-31 02:48

会将模板名被添加到 --> 需要将模板名称目录添加到 会更好一些

zhongqi 02-08 10:50

比如要在上面base.html的footer中添加内容,可以用{{ block.super }}先引入base中的原有内容,而不必全部重写。

melzg 03-20 15:11

单从这里看,没看明白{{ block.super }}标签如何使用。需要解释一下具体用法。

melzg 03-20 15:43

明白{{ block super }}的用法了。引入对应block后,在其前后,都可以增加相应的内容。如:{% block footer %} <b>This is the begin of footer.</b> {{ block.super }} <br/> <b>This is the end of footer.</b> {% endblock %}

lu4nx 05-27 14:42

@Woods:跟传递变量一样的...动态包含提交变量的内容..不过要注意这样可能出现一个潜在的 或者是 理论上的 任意文件包含漏洞...

sapjax 07-20 10:45

楼上正解

jackyzy823 11-04 13:46

尝试{%extends {{var}} %}这样的形式但是失败了。。。

jackyzy823 11-04 13:51

去掉var 外面的两个{}就可以了。。。。

Jerry 12-17 06:40

我想问这个支持多继承吗?

zjnjxufe 01-25 07:04

明白了。 你重写该block是会把父模板中该block的内容全部覆盖的。如果想要保存父模板的内容,就可以调用super

athos 03-09 01:50

附议,谢谢楼上诸位

chifa 04-24 02:10

感谢楼上各位大大

drgcaosheng 07-06 06:09

谢谢.楼上的.自己试验了下.明白了.

whatpc 07-17 08:07

变量在什么时候赋值?在views里面么?

zzm88 07-18 03:01

大谢!

byrain 07-19 08:51

试了下 在子类模板中引入{{ block.super }}, 就是把父类模板添加至此 多谢LS各位

Jahangir 08-08 18:41

@whatpc应该是在试图函数里面赋值,然后通过Context传递进来

atlas 09-13 15:26

@melzg 我在子模版里面不引入{{ block.super }}也可以啊

1/1 11-05 15:00

这个要注意

boban 11-27 07:32

“钩子越多越好”这句话有什么来历吗?

匿名读者 01-02 01:46

大谢!

rabbit 03-28 06:49

这个是什么意思呀。。<ExtendsNode: extends "base.html"> must be the first tag in the template. 应该怎么改

rabbit 03-28 07:11

明白了。。原来是因为我前面有注释的。。。把注释去掉就好了

牛三金 04-22 02:39

@boban 主模板基本很少改动,如果事先不标记好BLOCK,后期想要额外增加新元素将十分困难。

mihello 08-03 04:03

thanks, 和Flask的模板差不多

匿名读者 12-24 07:01

@boban 设计模式上有一种思想是面向接口编程 留下接口进行多样的实现 不影响整体的算法

grunmin 03-04 09:34

更换全套网页主题是否就是使用了这个方法?

monkeyfather 05-08 08:06

@Jahangir 试过,在views的hours_ahead函数里添加var=“base.html”,直接通过local()传递到hours_ahead.html模板中,成功。

psd 05-25 02:19

挖了个大坑。。。

mr.liu 06-03 03:57

回复楼上的,如果你没有使用local()来传递变量,而是使用字典方式或者其他,那直接在子模板里这样写{% extends parent_template %},parent_template是变量名称,不要{% extends {{ parent_template }} %},是错误的。

lou 06-25 09:26

读了许多遍,没读懂,英文版的也是,不知道这个比喻寓意何在。

lou 06-25 09:35

假设base定义了两个相同的{% block title %}, 那么在子类中是可能会混淆的(除非两个都重写)。 为了孩子,还是定义一个的好。

mr.liu 08-03 02:24

{{ block.super }}:如果在基础模板中一个代码块定义了内容,然后在子模板中使用此代码块时,若使用‘block.super’方法,将引用基础模板中此代码块定义的内容,倘若不使用,那基础模板中此代码的定义的内容将不会显示。例子:基础模板‘{% block footer %}<hr><p>Thanks for visiting my site.</p>{% endblock %}’子模板:‘{% block footer %}{{ block.super }}<hr><p>This is the end of footer.</p> {% endblock %}’。既想显示基础模板footer块内容,又想显示子模板footer块添加的内容,就添加{{ block.super }} 标签吧。

01 11-09 08:37

论 default value 的重要性

CopyStyle 12-17 05:28

为了孩子。。。

aaron 05-05 05:29

楼上正解 {% extends var %} 模板里这么应用就行 'var':var view.py文件中就跟传其他值一样在字典里传就行了

glimmer 05-29 01:53

即导入模板名称(如a.html)前会自动加上TEMPLATE_DIRS目录地址,形成绝对地址TEMPLATE_DIRS/a.html

glimmer 05-29 01:57

谢谢楼上

Cc 03-26 13:09

感谢楼上!

Sean 04-24 15:25

模版继承,说白了就是父亲建的房子,儿子在父亲房子的基础上装修了一下,然后孙子长大了,想换一种风格,然后就又在父亲的基础上,把儿子的装修风格拆了,自己又装了一下,可以是部分的, 也可以是全部的

流沙 11-14 02:37

html写法:{% extends base %} # base需要与views函数的返回参数头一致 views函数写法:return render(request, 'current_datetime.html', {"base": "base.html"})

猪头哥哥 11-30 08:10

楼上说的很对 你的html页面上extends的变量应当是个字符串 要么"base.html"这样写在页面上,要么就在传值的时候写在字典里传过来

lee 12-05 01:46

@lou 就是基模板不仅挖了个坑,还给坑填了个默认值

huhu 06-25 04:55

有点类似于装饰器?

Mawuhui 08-30 08:40

{% extends %} 这段代码必须放在第一行,前面不能加注释,不能加别的东西

雪雪 10-16 11:46

一个萝卜一个坑~

Ignora 01-24 11:23

学过信息安全的人也许会对“钩子越多越好”这句话有不同的理解

Ignora 01-24 11:30

比如基模板如果有两个<% block title %>,继承这个模板的模板如果只重写一个<% blcok title %>,则无法判断填的是哪一个block的东西。

nick 06-06 03:46

ls的不对啊。我前面加了一条p标签也是正常的呀

nick 06-06 03:55

是extends前面不能加block

匿名读者 10-12 07:44

就时追加的意思吧

对这一段的评论会显示在这里

下一章

fucker 02-14 09:11

Very Good

76 06-15 08:54

good

blackysy 07-01 10:52

Good job!

对这一段的评论会显示在这里

你现在已经掌握了模板系统的基本知识。 接下来呢?

对这一段的评论会显示在这里

时下大多数网站都是 数据库驱动 的:网站的内容都是存储在关系型数据库中。 这使得数据和逻辑能够彻底地分开(视图和模板也以同样方式对逻辑和显示进行了分隔。)

对这一段的评论会显示在这里

下一章将讲述如何与数据库打交道。

对这一段的评论会显示在这里