原创博文,转载请注明出处。

以前曾遇到过错误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模板引擎的研究的更多相关文章

  1. Django模板引擎的研究

    Django模板引擎的研究 原创博文,转载请注明出处. 以前曾遇到过错误Reverse for ‘*’ with arguments '()' and keyword arguments' not f ...

  2. Django模板引擎

    Django作为Web框架,需要一种很便利的方法动态地生成 HTML 网页,因此有了模板这个概念.模板包含所需 HTML 的部分代码以及一些特殊语法,特殊语法用于描述如何将视图传递的数据动态插入HTM ...

  3. Express:模板引擎深入研究

    深入源码 首先,看下express模板默认配置. view:模板引擎模块,对应 require('./view'),结合 res.render(name) 更好了解些.下面会看下 view 模块. v ...

  4. django模板引擎自定义变量

    定义临时变量: {% with i=1 %} {{i}} {% endwith %} 定义对临时变量操作的tag 在templatetags中创建set_val.py 内容是 from django ...

  5. django模板语法之include

    假如我们有以下模板index.html,代码为: <!DOCTYPE html> <html lang="en"> <head> <met ...

  6. Django 2.0 学习(13):Django模板继承和静态文件

    Django模板继承和静态文件 模板继承(extend) Django模板引擎中最强大也是最复杂的部分就是模板继承了,模板继承可以让我们创建一个基本的"骨架"模板,它可以包含网页中 ...

  7. Django模板简介

    在settings.py中有个TEMPLATES的设置,其中BACKEND用来配置Django模板引擎, DIRS 定义了一个目录列表,模板引擎按列表顺序搜索这些目录以查找模板源文件 一般我们都会把模 ...

  8. djando模板----第一django模板应用

    Django模板 我们已经知道,模板函数的函数的返回值就是返回给客户端的数据,但如果返回数据很复杂,如果一个非常大的html页面,直接将页面代码固化在python脚本文件中是不合适的,当然 也可以将h ...

  9. Django模板自定义标签和过滤器,模板继承(extend),Django的模型层

    上回精彩回顾 视图函数: request对象 request.path 请求路径 request.GET GET请求数据 QueryDict {} request.POST POST请求数据 Quer ...

随机推荐

  1. 一个数据表对象(NSManagedObject)加入排序

    eg:数据库表对象 @interface Meditation : NSManagedObject @property (nonatomic, retain) NSString * order;//用 ...

  2. MVC基本概念和流程

    MVC基本概念和流程 MVC的概念 Model(模型):包含数据和行为.不过现在一般都分离开来:Value Object(数据) 和 服务层(行为). View(视图):负责进行模型的展示,一般就是展 ...

  3. oracle_powerdesinger逆向工程 , PDM 文件 注释到name的完美解决方案 comment2name

    1. 从oracle 到 PDM文件  逆向工程中 ,需要注意 去掉“” ,这个百度下很多帖子,用于去掉引号 2. 从注释copy到name运行脚本会有个问题就是 ,有些注释太长,不美观 解决方案, ...

  4. linux_vim_快捷键

    1.vim ~/.vimrc 进入配置文件 如果不知道vimrc文件在哪,可使用 :scriptnames 来查看 set nu #行号 set tabstop=4 #一个tab为4个空格长度 set ...

  5. Linux下javaweb

    Linux下javaweb环境搭建 步骤: 1.使用远程工具连接上服务器,例如xsheel(ssh).filezilla(ftp) 2.JDK安装及相关配置 3.Mysql安装及相关配置 4.Tomc ...

  6. MyEclipse使用总结——MyEclipse文件查找技巧

    原文:MyEclipse使用总结--MyEclipse文件查找技巧 一.查找文件 使用快捷键[ctrl+shift+R]弹出弹出文件查找框,如下图所示: 二.查找包含某个字符串的文件 使用快捷键[ct ...

  7. UIAppDelegate介绍

    #import "GLAppDelegate.h" @implementation GLAppDelegate // 当应用程序启动完毕的时候就会调用(系统自动调用) - (BOO ...

  8. SQL Server日志文件庞大收缩方法(实测好用)

    原文:SQL Server日志文件庞大收缩方法(实测好用) 这两个命令连续执行,间隔时间越少越明显(可多次运行),直到达到效果 --截断 BACKUP LOG CloudMonitor TO DISK ...

  9. Unofficial Microsoft SQL Server Driver for PHP (sqlsrv)非官方的PHP SQL Server 驱动

    原文 Unofficial Microsoft SQL Server Driver for PHP (sqlsrv) Here are unofficial modified builds of Mi ...

  10. 关于jquery mobile 页面闪烁与抖动问题

    1.闪烁:在用a链接跳转到另一个页面的时候,页面总会抖动几下,其实就是页面切换时的transition特效,jqm貌似默认了这项. 解决方案:在a链接添加transition:none; 属性就可以啦 ...