关于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()方法。示例如下:
>>> from django.template import Template, Context
>>> raw_template = """<p>Dear {{ person_name }},</p>
...
... <p>Thanks for ordering {{ product }} 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>
... {% endif %}
...
... <p>Sincerely,<br />{{ company }}</p>"""
>>> t = Template(raw_template) 实例化Template对象
>>> import datetime
>>> c = Context({'person_name': 'John Smith', 实例化context对象
... 'product': 'Super Lawn Mower',
... 'company': 'Outdoor Equipment',
... 'ship_date': datetime.date(2009, 4, 2),
... 'ordered_warranty': True})
>>> t.render(c) 调用render方法
"<p>Dear John Smith,</p>\n\n<p>Thanks for ordering Super Lawn Mower from
Outdoor Equipment. It's scheduled \nto ship on April 2, 2009.</p>\n\n\n
<p>Your warranty information will be included in the packaging.</p>\n\n\n
<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模板引擎的研究
Django模板引擎的研究 原创博文,转载请注明出处. 以前曾遇到过错误Reverse for ‘*’ with arguments '()' and keyword arguments' not f ...
- 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 ...
随机推荐
- 采购申请 POCIRM-001:ORA-01403: 无论数据未找到
今天就让同事帮忙看问题.当请求生成采购订单,在销售模块错误提交销售订单 查看请求日志 +-------------------------------------------------------- ...
- rman(上)
CHANGE命令更改备份和副本的状态 1.change backupset 100 unavailable CATALOG命令是用来备份的碎片和复制信息到RMAN数据库 1.息增加到RMAN ...
- Swift——(三)Swift神奇的下划线
在Swift在.有许多神奇的下划线,在这里,我们将看到神奇的汇总,我希望能够帮助其他很多学习Swift朋友. @Author: twlkyao转载或者引用请保留此行. 1.格式化数字字面量 通 ...
- Oracle 用户权限管理方法
Oracle 用户权限管理方法 sys;//系统管理员,拥有最高权限 system;//本地管理员,次高权限 scott;//普通用户,密码默认为tiger,默认未解锁 sys;//系统管理员,拥有最 ...
- 使用pfile 启动oracle 实例时,启动失败---db_recovery_file_dest參数值在os上不存在。
[oracle@vm22 ~]$ export ORACLE_SID=orcl [oracle@vm22 ~]$ sqlplus / as sysdba SQL*Plus: Release 10.2. ...
- C#如何设置session过期时间
1.操作系统 步骤:开始——〉管理工具——〉Internet信息服务(IIS)管理器——〉网站——〉默认网站——〉 右键“属性”——〉主目录——〉配置——〉选项——〉启用会话状态——〉会话超时(在 ...
- BST(Binary Search Tree)
原文链接:http://blog.csdn.net/jarily/article/details/8679280 /****************************************** ...
- 接收终端Request.InputStream阅读
接收终端Request.InputStream阅读请求页面参数,最后字符串. byte[] byts = new byte[HttpContext.Current.Request.InputStrea ...
- TS流文件
简单介绍编辑 随着从HDTV录制的高清节目在网上的流传,烧友们对TS这个名词大概已经不陌生了.但随之而来就是怎样播放.怎样加入字幕等等的一系列问题.本文将重点介绍一下这方面的应用操作. 先来简要介绍一 ...
- 再议 js 数字格式之正则表达式
原文:再议 js 数字格式之正则表达式 前面我们提到到了js的数字格式<浅谈 js 数字格式类型>,之前的<js 正则练习之语法高亮>里也提到了优化数字匹配的正则.不过最近落叶 ...