Django模板引擎的研究
Django模板引擎的研究
原创博文,转载请注明出处。
以前曾遇到过错误Reverse for ‘*’ with arguments '()' and keyword arguments' not found.1其原因是没有给视图函数传入参数。解决方法传入参数即可。
可是今天又遇到了同样的问题,发现原来的方法不好使了。研究了一下午,我发现原来在我的模板文件中,有多个视图函数需要传入同一名称的参数。如果不能明白我所表达的意思可以见下图

可以看到在blog.urls 所对应的视图函数必定需要一个参数realid,这就带来了多个视图函数需要传入同一名称的参数的问题。
问题的解决是我无意间把context_instance=RequestContext(request)去掉换成locals()。
所以,我决定把模板引擎进行一番学习。出自Django book。
1、基本知识:模板是一个文本,用于分离文档的表现形式和内容。模板定义了占位符以及各种用于规范文档该如何显示的各部分基本逻辑(模板标签)。模板通常用于产生HTML,但是Django的模板也能产生任何基于文本格式的文档。我们通常将模板和视图一起使用(实际,不限于此)。
2、最简单的模板系统实现方法:
(1)创建一个Template对象,Django支持用知道模板文件路径的方式来创建Template对象。
(2)模板渲染:调用模板对象的render方法,并且传入一套变量context。它将返回一个基于模板的展示字符串,模板中的变量和标签会被context指替换。
context是一系列变量和它们值得集合。
总结起来就是:写模板,创建Template对象,创建Context,调用render()方法。示例如下:

1 >>> from django.template import Template, Context
2 >>> raw_template = """<p>Dear {{ person_name }},</p>
3 ...
4 ... <p>Thanks for ordering {{ product }} from {{ company }}. It's scheduled
5 ... to ship on {{ ship_date|date:"F j, Y" }}.</p>
6 ...
7 ... {% if ordered_warranty %}
8 ... <p>Your warranty information will be included in the packaging.</p>
9 ... {% endif %}
10 ...
11 ... <p>Sincerely,<br />{{ company }}</p>"""
12 >>> t = Template(raw_template) 实例化Template对象
13 >>> import datetime
14 >>> c = Context({'person_name': 'John Smith', 实例化context对象
15 ... 'product': 'Super Lawn Mower',
16 ... 'company': 'Outdoor Equipment',
17 ... 'ship_date': datetime.date(2009, 4, 2),
18 ... 'ordered_warranty': True})
19 >>> t.render(c) 调用render方法
20 "<p>Dear John Smith,</p>\n\n<p>Thanks for ordering Super Lawn Mower from
21 Outdoor Equipment. It's scheduled \nto ship on April 2, 2009.</p>\n\n\n
22 <p>Your warranty information will be included in the packaging.</p>\n\n\n
23 <p>Sincerely,<br />Outdoor Equipment</p>"

django.template.Template类构造函数接受一个参数,原始模板代码。
django.template.Context类的构造函数带有一个可选的参数:一个字典变量和它们的值。
可以看到输出中,模板对象中的‘person_name’被替换成了‘john Smith’,‘product’被替换成了‘Super Lawn Mower’等等。
3、强大的模板加载:可以从磁盘中加载模板,也就是说我们实现了视图函数和模板文件的分离。让它使用 Django 模板加载功能而不是对模板路径硬编码。
首先我们必须设置settings.py里面的TEMPLATE_DIRS,将模板的保存位置告诉框架。这里我们介绍一种使用相对路径的方法
import os.path TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)
os.path.dirname(__file__)将会获取自身所在的文件,即settings.py 所在目录,然后由os.path.join这个方法将这目录与templates进行连接。前提是我们需要创建一个templates文件夹来存放模板文件

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)

此范例中,我们使用了函数 django.template.loader.get_template() ,而不是手动从文件系统加载模板。该 get_template() 函数以模板名称为参数,在文件系统中找出模块的位置,打开文件并返回一个编译好的 Template 对象。如果 get_template() 找不到给定名称的模板,将会引发一个 TemplateDoesNotExist 异常。
render_to_response()
由于加载模板、填充 context 、将经解析的模板结果返回为 HttpResponse 对象这一系列操作实在太常用了,Django 提供了一条仅用一行代码就完成所有这些工作的捷径。该捷径就是位于 django.shortcuts 模块中名为 render_to_response() 的函数。大多数时候,你将使用 render_to_response() ,而不是手动加载模板、创建 Context 和 HttpResponse 对象。
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})
render_to_response() 的第一个参数必须是要使用的模板名称。如果要给定第二个参数,那么该参数必须是为该模板创建Context 时所使用的字典。如果不提供第二个参数, render_to_response() 使用一个空字典。
Python 的内建函数 locals() 。它返回的字典对所有局部变量的名称与值进行映射。这可给你省了不少事情,但前提必须是变量的名称和模板文件被替换的值必须一致。因此,我们将 now 变量重命名为 current_date 。
def current_datetime(request):
current_date = datetime.datetime.now()
return render_to_response('current_datetime.html', locals())
同时,locals() 还包含了 request 。
RequestContext和Context处理器
RequestContext 默认地在模板context中加入了一些变量,如 HttpRequest 对象或当前登录用户的相关信息。
当你不想在一系例模板中都明确指定一些相同的变量时,你应该使用 RequestContext 。Context处理器允许你设置一些变量,它们会在每个context中自动被设置好,而不必每次调用 render_to_response() 时都指定。要点就是,当你渲染模板时,你要用 RequestContext 而不是 Context 。
建议选择 render_to_response() 作为context的处理器。像这样,使用 context_instance 参数,调用processors:

from django.shortcuts import render_to_response
from django.template import RequestContext def custom_proc(request):
"A context processor that provides 'app', 'user' and 'ip_address'."
return {
'app': 'My app',
'user': request.user,
'ip_address': request.META['REMOTE_ADDR']
} def view_1(request):
# ...
return render_to_response('template1.html',
{'message': 'I am view 1.'},
context_instance=RequestContext(request, processors=[custom_proc])) def view_2(request):
# ...
return render_to_response('template2.html',
{'message': 'I am the second view.'},
context_instance=RequestContext(request, processors=[custom_proc])) def view_3(request):
# ...
return render_to_response('template3.html',
{'message': 'I am the third view.'},
context_instance=RequestContext(request, processors=[custom_proc])) def view_4(request):
# ...
return render_to_response('template4.html',
{'message': 'I am the fourth view.'},
context_instance=RequestContext(request, processors=[custom_proc]))

同时,Django因此提供对 全局 context处理器的支持。Django提供了几个简单的context处理器,我们只需要在settings.py文件中配置:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
)
关于这几个处理器所返回的参数,可以详见Django book
回到我所遇到的问题,由于我的视图函数中的,有的使用了RequestContext 有的使用了locals(),返回的参数各不相同,导致视图函数无法得到realid值,也许表达不够清晰。举个例子,我的视图函数中使用了context_instance=RequestContext(request),但是我却令模板中的<a href={% url addarticle realid=request.user.id %}> 参数realid值为request.user.id,这就出现了错误,当你添加了locals()后就可以使用了,因为locals()返回request参数。
所以,为了方便,我把所有的视图函数加载模板的部分都改成了这个形式:
return render_to_response("**.html",locals(),context_instance=RequestContext(request))
Django模板引擎的研究的更多相关文章
- 关于Django模板引擎的研究
原创博文,转载请注明出处. 以前曾遇到过错误Reverse for ‘*’ with arguments '()' and keyword arguments' not found.1其原因是没有给视 ...
- Django模板引擎
Django作为Web框架,需要一种很便利的方法动态地生成 HTML 网页,因此有了模板这个概念.模板包含所需 HTML 的部分代码以及一些特殊语法,特殊语法用于描述如何将视图传递的数据动态插入HTM ...
- Express:模板引擎深入研究
深入源码 首先,看下express模板默认配置. view:模板引擎模块,对应 require('./view'),结合 res.render(name) 更好了解些.下面会看下 view 模块. v ...
- django模板引擎自定义变量
定义临时变量: {% with i=1 %} {{i}} {% endwith %} 定义对临时变量操作的tag 在templatetags中创建set_val.py 内容是 from django ...
- django模板语法之include
假如我们有以下模板index.html,代码为: <!DOCTYPE html> <html lang="en"> <head> <met ...
- Django 2.0 学习(13):Django模板继承和静态文件
Django模板继承和静态文件 模板继承(extend) Django模板引擎中最强大也是最复杂的部分就是模板继承了,模板继承可以让我们创建一个基本的"骨架"模板,它可以包含网页中 ...
- Django模板简介
在settings.py中有个TEMPLATES的设置,其中BACKEND用来配置Django模板引擎, DIRS 定义了一个目录列表,模板引擎按列表顺序搜索这些目录以查找模板源文件 一般我们都会把模 ...
- djando模板----第一django模板应用
Django模板 我们已经知道,模板函数的函数的返回值就是返回给客户端的数据,但如果返回数据很复杂,如果一个非常大的html页面,直接将页面代码固化在python脚本文件中是不合适的,当然 也可以将h ...
- Django模板自定义标签和过滤器,模板继承(extend),Django的模型层
上回精彩回顾 视图函数: request对象 request.path 请求路径 request.GET GET请求数据 QueryDict {} request.POST POST请求数据 Quer ...
随机推荐
- Linq的Distinct太不给力了[转]
假设我们有一个类:Product public class Product { public string Id { get; set; } public string Name { get; set ...
- css布局之选择切换按钮
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 计算4000000000内的最大f(n)=n值---字符串的问题python实现(五岁以下儿童)
问题: 写一个函数,计算4 000 000 000 以内的最大的那个f(n)=n的值,函数f的功能是统计全部0到n之间全部含有数字1的数字和.比方:f(13)= 6,由于"1"在& ...
- Opencv on Ubuntu (from Ubuntu)
OpenCV Introduction Contents Introduction Installation Step 1 Step 2 Running OpenCV Python in C I ...
- JS中5秒中跳转到其他页面
原文:JS中5秒中跳转到其他页面 <head> <meta http-equiv="Content-Type" content="text/html; ...
- android学习8(ListView高级使用)
ListView在android更开放的,于是继续ListView说明使用. 首先创建一个android项目,项目名为ListViewTest. ListView的简单使用 改动布局文件,改动后代码例 ...
- ASP.NET如何显示农历时间
ASP.NET如何显示农历时间 CS部分代码如下: 代码如下: public string ChineseTimeNow = ""; public string ForignTi ...
- AngularJS + CoffeeScript
AngularJS + CoffeeScript 前端开发环境配置详解 AngularJS 号称 '第一框架' ('The first framework') 确实是名不虚传.由其从jQuery中完全 ...
- .NET源代码的内部排序实现
使用JetBrains的DotPeek工具能够方便地查看.net的部分源代码.于是看了一下.NET的内部是怎样实现排序的算法. 在System.Collections.Generic 命名空间下能够看 ...
- Javascript--dataTransfer
描述: 提供对于预定义的剪贴板格式的访问,以便在拖拽中使用 属性 描述 参数 dropEffect[=sCursorStyle] 设置或获取拖拽操作的类型和要显示的光标类型 可选的copy 复制样式被 ...