django--模板的加载和导入

模板加载

为了减少模板加载调用过程及模板本身的冗余代码,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 字典,则可以避免这种开销。

你可能感兴趣的:(django)