注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

being23

写给未来的自己

 
 
 

日志

 
 
关于我

真正的坚定,就是找到力量去做自己喜欢的事情,并为之努力,这样才会觉得生活是幸福的。

网易考拉推荐

20131110  

2013-11-10 13:11:22|  分类: work@oppo |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

原文见 http://www.tangowithdjango.com/book/chapters/templates_static.html#


4. 模板与静态文件

在本章中,我们会通过向你展示模板引擎以及如何在网页中提供静态文件带你进一步领略Django的风采。

4.1. 使用模板

到目前为止,你已经将几个部件组装到一起创建了一个Django驱动的网页。这包含一个视图,以及由视图带来的一系列URL映射。这里,我们将深入研究如何将模板组合进来。

良好设计的网站在它们的结构或者架构中有大量重复使用的组件。无论你在一个网页中看到的header还是footer,重复的页面结构有助于用户浏览,改进网站的组织以及加强某种连贯性。Django提供了模板使得开发者能够轻松的完成这个目标,同时将应用逻辑从展示分离开。在本章中,你将创建一个基本的模板,其被用来生成一个HTML页面。这个模板会通过Django视图发送。在第六章,我们进一步联合使用模型和模板来发送动态生成的数据。

4.1.1 配置模板目录

要使用模板,你需要创建一个目录来存放模板文件。

在你的Django工程目录中(例如 <workspace>/tango_with_django_project/),创建一个名为templates的目录。在新建的模板目录中,再创建一个名为rango的目录。这样一来,目录<workspace>/tango_with_django_project/templates/rango/就是用来存放rango工程相关模板的地方。

打开工程的settings.py文件,来设置模板如何存放。找到元组TEMPLATE_DIRS,在其中加入新创建的template目录的路径,类似下面这个例子。

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    '<workspace>/tango_with_django_project/templates/',
)

注意到这里指向templates目录的路径是绝对路径。如果你是某个团队的成员或者在不同的电脑上工作,这在以后可能会带来问题。你可能使用不同的用户名,这意味着<workspace>的路径是不同的。当然了,你可以在每个不同的设置中添加模板目录,不过这是一个相当蛋疼的解决方案。

注意:地狱之路是硬编码铺就的。(The road to hell is paved with hard-coded paths.)硬编码的路径被认为是软件工程的反模式,降低工程的可移植性

相反,我们可以做的更加智能,使用python的内置函数来获得模板目录的路径,与你的工程在文件系统中位置无关。虽然这么做,在建立Django工程时会费点事,不过当后面需要在另一台电脑上运行工程时会轻松许多。No pain,no gain!

修改文件settings.py,在其中添加表示工程绝对路径的变量PROJECT_PATH。这可以通过向操作系统询问当前工作目录完成。在settings.py的顶部,添加下面两行代码。

import os
PROJECT_PATH = os.getcwd()

这行代码导入了Python的os模块并获取当前工作目录的路径。你就是在这个路径下执行python manage.py runserver启动server 的。将这个路径值赋给变量PROJECT_PATH

将工程根目录的绝对路径存到PROJECT_PATH之后,我们可以将这个路径和子目录或者文件名组合到一起来获取工程资源的完整路径。

在文件settings.py中新建变量TEMPLATE_PATH,像下面这样将模板目录的路径存到其中:

TEMPLATE_PATH = os.path.join(PROJECT_PATH, 'templates')

这里,我们使用了函数os.path.join()来处理链接。这是推荐的做法——使用这个函数可以保证正确的使用不同操作系统中路径分隔符(就是”\”或者”/”)。在元组TEMPLATES_DIR中,增加如下的引用:

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    TEMPLATE_PATH,
)

我们将变量TEMPLATE_PATH放在文件settings.py的顶端使得它很容易看到。这就是为什么创建一个额外的变量来存放模板路径。

4.1.2. 添加模板

设置好模板目录和路径之后,新建文件index.html,保存到目录templates/rango/。在这个文件中,输入下面的HTML代码:

<!DOCTYPE html>
<html>

    <head>
        <title>Rango</title>
    </head>

    <body>
        <h1>Rango says...</h1>
        hello world! <strong>{{ boldmessage }}</strong><br />
        <a href="/rango/about/">About</a><br />
    </body>

</html>

根据上面的HTML,我们可以清楚的知道会生成一个简单的HTML页面,它给用户返回一句hello world消息。你也许还注意到了一些非HTML的元素{{ boldmessage }}。这是一个Django模板变量,我们可以在渲染输出中设置这个变量的值。一会儿就会讲到了。

要使用这个模板,我们需要重新配置之前创建的index()视图。不再发送一条简单的消息,而是改成发送我们的模板。

在文件rango/views.py的顶部,增加下面的导入语句。

from django.template import RequestContext
from django.shortcuts import render_to_response

更新视图index()如下。留意行间的注释以弄明白它们是做什么的。

def index(request):
    # Request the context of the request.
    # The context contains information such as the client's machine details, for example.
    context = RequestContext(request)

    # Construct a dictionary to pass to the template engine as its context.
    # Note the key boldmessage is the same as {{ boldmessage }} in the template!
    context_dict = {'boldmessage': "I am from the context"}

    # Return a rendered response to send to the client.
    # We make use of the shortcut function to make our lives easier.
    # Note that the first parameter is the template we wish to use.
    return render_to_response('rango/index.html', context_dict, context)

在我们更新后的视图中,我们通过类RequestContext来访问跟用户request相关的设置。然后新建一个字典来存放想要通过模板发送的数据,最后调用函数render_to_response()。我们把需要使用的模板,存放模板变量的字典以及从用户request中获取的上下文作为参数传递。函数render_to_response()接收这些参数,将它们和模板组合到一起生成一个完整的HTML页面。将页面返回并发送到用户的浏览器。

当Django模板系统载入一个模板文件时,就会创建一个template context(模板上下文)。简单的说,一个模板上下文本质上就是一个python字典,它将模板变量映射到python变量。在之前创建的模板当中,我们引入了一个模板变量boldmessage。在示例视图index(request)中,字符串I am from the context就被映射到了模板变量boldmessage中。因为,字符串I am from the context就会替换模板中出现的任何{{ boldmessage }}

现在你可以更新视图来部署你的模板应用,运行Django的开发服务器并访问http://127.0.0.1:8000/rango/。你就会看到模板被渲染好了,就像图1中看到的那样。

rango-hello-world-template

如果没有看到,看下错误消息弄明白问题出在哪,然后检查你所作的修改。保证所有需要的修改都已完成。一个常见的问题就是在文件settings.py中没有设对路径。有时可以在settings.py中添加一个print语句来打印出PROJECT_PATHTEMPLATE_PATH

这个例子说明了如何在视图中使用模板。不过,我们只是接触了Django模板系统的一些皮毛而已。随着讲解的深入,我们会以更复杂的方式来使用模板。同时,你可以在templates from the official Django documentation找到更多的关于模板的资料。

4.2. 静态文件

显然,站点Rango还是相当的一般,因为没有包含任何styling或者imagery。CCSJavaScript以及图片从本质上来说是静态文件,我们可以把它们添加到网页中从而增加style并引入动态的行为。这些文件以一种稍微不同于网页的方式被处理。这是由于他们的生成方式不同于HTML页面。本节会讲解如何设置Django工程来想客户提供静态文件。我们还有修改模板来包含一些示例的静态文件。

4.2.1 配置静态文件目录

要提供静态文件,我们需要建立一个目录来存放静态文件。在你的工程目录中(例如<workspace>/tango_with_django_project/),新建目录static

现在把一张图片放到目录static中。如图2,我们选取了一张变色龙的图片,Rango —— 一个合适的吉祥物,如果有的话。

rango-picture

建立好static目录后,我们需要告知Django,就像之前对templates目录所做的。在文件settings.py中,我们需要修改两个变量STATIC_URLSTATICfFILES_DIRS元组。首先,新建变量来存放静态文件的目录(STATIC_PATH)如下:

STATIC_PATH = os.path.join(PROJECT_PATH,'static')

STATIC_URL = '/static/' # You may find this is already defined as such.

STATICFILES_DIRS = (
    STATIC_PATH,
)

你输入了一些代码,但是这表示什么呢?第一个变量STATIC_URL定义了基本的URL,当服务器运行时,Django应用可以通过它找到静态文件。例如,当运行开发服务器时,STATIC_URL想上面那样设为/static/,那么就可以通过http://127.0.0.1:8000/static/访问静态文件。文档official documentation on serving up static media强调保证地址中的斜杠跟这里一致灰常重要。忘记了这个配置会灰常痛苦。

STATIC_URL定义了通过web服务器访问静态文件的URL,STATICFILES_DIRS允许你指定新建的static目录在磁盘中的路径。就像TEMPLATES_DIRSTATICFILES_DIRS要求static的绝对路径。这里,我们重用了4.1节定义的PROJECT_PATH来定义STATIC_PATH

搞定这两处设置,再次运行Django工程的开发服务器。如果我们想看到我们的Rango图片,访问http://127.0.0.1:8000/static/rango.jpg。如果图片没有出现,你需要检查拼写是否正确,文件settings.py有没有保存,重启开发服务器。如果出现了,在static目录中放入不同类型的文件,并通过浏览器来访问。

注意:使用Django的开服务器来访问静态文件对于开发环境是没有问题的,不过非常不适用于生产环境。文档official Django documentation on Deployment说明了如何在生产环境部署静态文件。

4.3. 静态文件与模板

现在你的Django工程中已经能够处理静态文件了,你可以在模板中访问这些文件。

要说明如何将静态文件包含进来,打开位于<workspace>/templates/rango/目录中的index.html文件。修改HTML源码如下。带有注释的两行代码是我们添加进去的,很容易找到。

<!DOCTYPE html>

{% load static %} <!-- New line -->

<html>

    <head>
        <title>Rango</title>
    </head>

    <body>
        <h1>Rango says...</h1>
        hello world! <strong>{{ boldmessage }}</strong><br />
        <a href="/rango/about/">About</a><br />
        <img src="{% static "rango.jpg" %}" alt="Picture of Rango" /> <!-- New line -->
    </body>

</html>

首先,我们需要告知Django的模板系统,我们将通过标签{% load static %}来使用静态文件。这允许我们像{% static "rango.jpg" %}这样来调用static模板标签。如你所见,Django的模板标签是由{ }表示的。在这个例子中,static标签会将STATIC_URL"rango.jpg"拼装到一起,这样渲染后得到的HTML看起来是这个样子。

<img src="/static/rango.jpg" alt="Picture of Rango" /> <!-- New line -->

如果由于某些原因不能载入图片, it is always nice to specify an alternative text tagline。这就是alt属性提供的——这里的文本用于图片载入失败。

做好上面这些小改动,再次启动开发服务器并访问http://127.0.0.1:8000/rango。不出意外,你将会看到如图3的网页。

rango-site-with-pic

每当你想在模板中访问静态文件记得使用{% static %}函数。下面的示例代码说明了如何在模板中使用JavaScript,CSS以及图片——all with the correct HTML markup。

<!DOCTYPE html>

{% load static %}

<html>

    <head>
        <title>Rango</title>
        <link rel="stylesheet" href="{% static "css/base.css" %}" /> <!-- CSS -->
        <script src="{% static "js/jquery.js" %}"></script> <!-- JavaScript -->
    </head>

    <body>
        <h1>Including Static Media</h1>
        <img src="{% static "rango.jpg" %}" alt="Picture of Rango" /> <!-- Images -->
    </body>

</html>

显然,你能访问到的静态文件需要位于static目录。如果文件不在该目录或者访问方式不对,Django的轻量级服务器会在控制台中输出任何错误。试着去访问一个不存在的文件,看看会发生什么。

访问静态文件的更多资料,见文档 Django documentation on working with static files in templates

4.4. 静态文件服务器

现在你已经能够发送静态文件了,再看下上传文件。很多站点都对用户提供了这个功能——例如,上传一张个人头像。本节会介绍如何在Django工程中添加一个简单的开发用静态文件服务器。这个服务器可以与第八章会介绍的文件上传表单配合使用。

嗯,我们要如何来搭建这样一个服务呢?首先在Django工程的根目录中新建一个名为media的目录(例如,<workspace>/tango_with_django_project/)。这个新建的media目录应该跟目录templatesstatic在一起。建好目录后,修改位于工程目录的urls.py文件(例如,<workspace>/tango_with_django_project/tango_with_django_project/)。在文件urls.py中添加如下内容。

# At the top of your urls.py file, add the following line:
from django.conf import settings

# UNDERNEATH your urlpatterns definition, add the following two lines:
if settings.DEBUG:
        urlpatterns += patterns(
                'django.views.static',
                (r'media/(?P<path>.*)',
                'serve',
                {'document_root': settings.MEDIA_ROOT}), )

通过django.confsettings模块,我们可以访问在工程settings.py文件中定义的变量。条件语句检测Django工程是否运行在DEBUG模式。如果工程的DEBUG选项打开,那么会在urlpatterns元组中添加一个额外的URL匹配模式。这个模式说明,任意一个以media/开头的文件请求,都会转给django.views.static视图。这个视图负责处理上传的文件。

更新完urls.py文件,我们需要修改工程的settings.py文件。我们需要设置两个变量。在你的文件中,找到MEDIA_URLMEDIA_ROOT,设置成如下值。

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media') # Absolute path to the media directory

第一个变量MEDIA_URL定义了一个基本的URL,通过它所有的静态文件都可以在开发服务器上访问。例如MEDIA_URL的值为/media/,那么用户上传的文件可以通过这个URL访问http://127.0.0.1:8000/media/MEDIA_ROOT用来告诉Django上传的文件应该存到本地磁盘位置。在上面的例子中,这个变量的值为PROJECT_PATH/media/组合后的值。这会得到一个绝对路径<workspace>/tango_with_django_project/media/

你可以将一个图片文件丢到刚刚创建的media目录中来做测试。把文件放进去,启动Django开发服务器,在浏览器中访问这个文件。例如,如果你将文件rango.jpg放到了目录media中,那么你访问的URL应该是http://127.0.0.1:8000/media/rango.jpg。这个图片应该在你的浏览器中出现。如果没有,需要退回检查下步骤吧。

4.5. 基本流程

到本章结束,你应该弄明白了如何新建模板,在视图中使用模板,通过Django发送静态文件,在模板中包含文件以及建立用于上传文件的服务。内容有点多!

建立模板并将其集成到Django视图中是你需要理解的一个关键概念。它需要多个步骤,不过多试几次它就会成为你的第二本能(second nature)。

  1. 首先,创建需要的模板,并将它保存到工程配置文件settings.py中指定的templates目录中。你你可以在模板中使用模板变量(例如,{{ variable_name }})。你可以在相应的视图中将其替换成你想要的变量名。
  2. 在应用视图文件views.py中找到或者新建一个视图。
  3. 在视图中添加视图相关的逻辑(如果有的话)。例如,这可能会包含从数据库中获取数据。
  4. 在视图中,创建一个字典对象,作为模板上下文的一部分传给模板引擎。
  5. 使用RequestContext()render_to_response()来生成渲染后的响应。render_to_response()的第一个参数要保证是争取的模板文件。
  6. 修改工程的urls.py文件以及应用相关的urls.py文件将视图映射到URL,如果你还没这么干的话。

获取静态文件到网页中是另一个你需要熟悉的过程。看下下面的步骤这是如何做到的。

  1. 将需要使用的静态文件放到工程的static目录。这个目录是你在文件settings.py里面的元组STATICFILES_DIRS中指定的。
  2. 在模板中添加一个对静态文件的引用。例如,一张图片将会通过<img />标签插入到网页中。记得使用命令{% load static %}{% static "filename" %}
  3. 在浏览器中载入使用修改后的模板的视图。你的静态文件就会出现了。

下一章,我们会介绍数据库。我们会看到如何使用Django的数据库层来使得工作变轻松并且与SQL无关。

2013-11-10 @深圳 南山

  评论这张
 
阅读(465)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017