django--模板的加载和导入

本文介绍了Django框架中模板的加载方式与渲染流程。详细讲述了如何配置模板目录、使用Django API加载模板以及简化视图函数的方法。

模板加载

为了减少模板加载调用过程及模板本身的冗余代码,Django 提供了一种使用方便且功能强大的 API ,用于从磁盘中加载模板,

要使用此模板加载API,首先你必须将模板的保存位置告诉框架。该项工作在 设置文件 中完成。

Django 设置文件是存放 Django 实例(也就是 Django 项目)配置的地方。它是一个简单的 Python 模块,其中包含了一些模块级变量,每个都是一项设置。

第二章中执行 django-admin.py startproject mysite 命令时,它为你创建了一个的缺省配置文件,并恰如其分地将其名为settings.py 。查看一下该文件内容。其中包含如下变量(但并不一定是这个顺序):

DEBUG = True
TIME_ZONE = 'America/Chicago'
USE_I18N = True
ROOT_URLCONF = 'mysite.urls'

这里无需更多诠释;设置项与值均为简单的 Python 变量。同时由于配置文件只不过是纯 Python 模块,你可以完成一些动态工作,比如在设置某变量之前检查另一变量的值。(这也意味着你必须避免配置文件出现 Python 语法错误。)

我们将在附录 E 中详述配置文件,目前而言,仅需关注 TEMPLATE_DIRS 设置。该设置告诉 Django 的模板加载机制在哪里查找模板。缺省情况下,该设置的值是一个空的元组。选择一个目录用于存放模板并将其添加到 TEMPLATE_DIRS 中:

TEMPLATE_DIRS = (
    '/home/django/mysite/templates',
)

下面是一些注意事项:

你可以任意指定想要的目录,只要运行 Web 服务器的用户账号可以读取该目录的子目录和模板文件。如果实在想不出合适的位置来放置模板,我们建议在 Django 项目中创建一个 templates 目录(也就是说,如果你一直都按本书的范例操作的话,在第二章创建的 mysite 目录中)。

不要忘记模板目录字符串尾部的逗号!Python 要求单元素元组中必须使用逗号,以此消除与圆括号表达式之间的歧义。这是新手常犯的错误。

想避免此错误的话,你可以将列表而不是元组用作 TEMPLATE_DIRS ,因为单元素列表并不强制要求以逗号收尾:

TEMPLATE_DIRS = [
    '/home/django/mysite/templates'
]

从语义上看,元组比列表略显合适(元组在创建之后就不能修改,而配置被读取以后就不应该有任何修改)。因此,我们推荐对 TEMPLATE_DIRS 设置使用元组。

如果使用的是 Windows 平台,请包含驱动器符号并使用Unix风格的斜杠(/)而不是反斜杠(\),就像下面这样:

TEMPLATE_DIRS = (
    'C:/www/django/templates',
)

最省事的方式是使用绝对路径(即从文件系统根目录开始的目录路径)。如果想要更灵活一点并减少一些负面干扰,可利用 Django 配置文件就是 Python 代码这一点来动态构建 TEMPLATE_DIRS 的内容,如:

import os.path

TEMPLATE_DIRS = (
    os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)

这个例子使用了神奇的 Python 内部变量 __file__ ,该变量被自动设置为代码所在的 Python 模块文件名。

完成 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)

此范例中,我们使用了函数 django.template.loader.get_template() ,而不是手动从文件系统加载模板。该 get_template() 函数以模板名称为参数,在文件系统中找出模块的位置,打开文件并返回一个编译好的 Template 对象。


Template()和get_template()方法的区别:

Template()是Templste类的一个实例:可以接收原版的模板代码为参数,也可以接收赋值为模板原始代码的变量!
example:
from django.template import Template,Context
def img(req,id):
t = Template('my id is {{id}}')
c = Context({'id':id})
response = t.render(c)
return HttpResponse(response)

get_template() 函数以模板名称为参数,在文件系统中找出模块的位置,打开文件并返回一个编译好的 Template 对象:
example:
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)

 

render_to_response()

由于加载模板、填充 context 、将经解析的模板结果返回为 HttpResponse 对象这一系列操作实在太常用了,Django 提供了一条仅用一行代码就完成所有这些工作的捷径。该捷径就是位于 django.shortcuts 模块中名为 render_to_response() 的函数。大多数时候,你将使用 render_to_response() ,而不是手动加载模板、创建 Context 和 HttpResponse 对象。

下面就是使用 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})

大变样了!让我们逐句看看代码发生的变化:

  • 我们不再需要导入 get_template 、 Template 、 Context 和 HttpResponse 。相反,我们导入django.shortcuts.render_to_response 。 import datetime 继续保留

  • 在 current_datetime 函数中,我们仍然进行 now 计算,但模板加载、上下文创建、模板解析和 HttpResponse 创建工作均在对 render_to_response() 的调用中完成了。由于 render_to_response() 返回 HttpResponse 对象,因此我们仅需在视图中 return 该值。

     

render_to_response() 的第一个参数必须是要使用的模板名称。如果要给定第二个参数,那么该参数必须是为该模板创建Context 时所使用的字典。如果不提供第二个参数, render_to_response() 使用一个空字典。

 

locals() 技巧

 

 

思考一下我们对 current_datetime 的最后一次赋值:

 

 

def current_datetime(request):

now = datetime.datetime.now() return render_to_response('current_datetime.html', {'current_date': now})

很多时候,就像在这个范例中那样,你发现自己一直在计算某个变量,保存结果到变量中(比如:前面代码中的 now ),然后将这些变量发送给模板。特别懒的程序员可能注意到给这些临时变量  模板变量命名显得有点多余。不但多余,而且还要进行额外的键盘输入。

 

 

如果你是个喜欢偷懒的程序员并想让代码看起来更加简明,可以利用 Python 的内建函数 locals() 。它返回的字典对所有局部变量的名称与值进行映射。因此,前面的视图可以重写成下面这个样子:

 

 

def current_datetime(request):

current_date = datetime.datetime.now() return render_to_response('current_datetime.html', locals())

在此,我们没有像之前那样手工指定 context 字典,而是传入了 locals() 的值,它囊括了函数执行到该时间点时所定义的一切变量。因此,我们将 now 变量重命名为 current_date ,因为那才是模板所预期的变量名称。在本例中, locals() 并没有带来多 的改进,但是如果有多个模板变量要界定而你又想偷懒,这种技术可以减少一些键盘输入。

 

 

使用 locals() 时要注意是它将包括 所有 的局部变量,组成它的变量可能比你想让模板访问的要多。在前例中, locals() 还包含了 request 。对此如何取舍取决你的应用程序。

 

 

最后要考虑的是在你调用 locals() 时,Python 必须得动态创建字典,因此它会带来一点额外的开销。如果手动指定 context 字典,则可以避免这种开销。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值