| ID | English原文 | 中文翻译 | 最近翻译记录 | 状态 | 操作 |
|---|---|---|---|---|---|
| 0#翻译 | Chapter 13: | 第十三章: | 翻译 | ||
| 1#翻译 | Generating Non-HTML Content | 输出非HTML内容 | 翻译 | ||
| 4#翻译 | Usually when we talk about developing Web sites, we're talking about producing HTML. | 通常当我们谈到开发网站时,主要谈论的是HTML。 | 翻译 | ||
| 5#翻译 | Of course, there's a lot more to the Web than HTML; we use the Web to distribute data in all sorts of formats: | 当然,Web远不只有HTML,我们在Web上用多种格式来发布数据: | 翻译 | ||
| 6#翻译 | RSS, PDFs, images, and so forth. | RSS、PDF、图片等。 | 翻译 | ||
| 8#翻译 | So far, we've focused on the common case of HTML production, but in this chapter we'll take a detour and look at using Django to produce other types of content. | 到目前为止,我们的注意力都是放在常见 HTML 代码生成上,但是在这一章中,我们将会对使用 Django 生成其它格式的内容进行简要介绍。 | 翻译 | ||
| 10#翻译 | Django has convenient built-in tools that you can use to produce some common non-HTML content: | Django拥有一些便利的内建工具帮助你生成常见的非HTML内容: | 翻译 | ||
| 12#翻译 | RSS/Atom syndication feeds | RSS/Atom 聚合文件 | 翻译 | ||
| 14#翻译 | Sitemaps (an XML format originally developed by Google that gives hints to search engines) | 站点地图 (一个XML格式文件,最初由Google开发,用于给搜索引擎提示线索) | 翻译 | ||
| 16#翻译 | We'll examine each of those tools a little later, but first we'll cover the basic principles. | 我们稍后会逐一研究这些工具,不过首先让我们来了解些基础原理。 | 翻译 | ||
| 18#翻译 | The basics: | 基础: | 翻译 | ||
| 19#翻译 | views and MIME-types | 视图和MIME类型 | 翻译 | ||
| 21#翻译 | Recall from Chapter 3 that a view function is simply a Python function that takes a Web request and returns a Web response. | 回顾一下第三章,视图函数只是一个以Web请求为参数并返回Web响应的Python函数。 | 翻译 | ||
| 22#翻译 | This response can be the HTML contents of a Web page, or a redirect, or a 404 error, or an XML document, or an imageor anything, really. | 这个响应可以是一个Web页面的HTML内容,或者一个跳转,或者一个404 错误,或者一个XML文档,或者一幅图片,或者映射到任何东西上。 | 翻译 | ||
| 24#翻译 | More formally, a Django view function <emphasis>must</emphasis> | 更正式的说,一个Django视图函数 <emphasis>必须</emphasis> | 翻译 | ||
| 26#翻译 | Accept an <literal>HttpRequest</literal> instance as its first argument | 接受一个 <literal>HttpRequest</literal> 实例作为它的第一个参数 | 翻译 | ||
| 28#翻译 | Return an <literal>HttpResponse</literal> instance | 返回一个 <literal>HttpResponse</literal> 实例 | 翻译 | ||
| 30#翻译 | The key to returning non-HTML content from a view lies in the <literal>HttpResponse</literal> class, specifically the <literal>mimetype</literal> argument. | 从一个视图返回一个非 HTML 内容的关键是在构造一个 <literal>HttpResponse</literal> 类时,需要指定 <literal>mimetype</literal> 参数。 | 翻译 | ||
| 31#翻译 | By tweaking the MIME type, we can indicate to the browser that we've returned a response of a different format. | 通过改变 MIME 类型,我们可以通知浏览器将要返回的数据是另一种类型。 | 翻译 | ||
| 33#翻译 | For example, let's look at a view that returns a PNG image. | 下面我们以返回一张PNG图片的视图为例。 | 翻译 | ||
| 34#翻译 | To keep things simple, we'll just read the file off the disk: | 为了使事情能尽可能的简单,我们只是读入一张存储在磁盘上的图片: | 翻译 | ||
| 37#翻译 | That's it! | 就是这么简单。 | 翻译 | ||
| 38#翻译 | If you replace the image path in the <literal>open()</literal> call with a path to a real image, you can use this very simple view to serve an image, and the browser will display it correctly. | 如果改变 <literal>open()</literal> 中的图片路径为一张真实图片的路径,那么就可以使用这个十分简单的视图来提供一张图片,并且浏览器可以正确显示它。 | 翻译 | ||
| 40#翻译 | The other important thing to keep in mind is that <literal>HttpResponse</literal> objects implement Python's standard file-like object API. | 另外我们必须了解的是<literal>HttpResponse</literal>对象实现了Python标准的文件应用程序接口(API)。 | 翻译 | ||
| 41#翻译 | This means that you can use an <literal>HttpResponse</literal> instance in any place Python (or a third-party library) expects a file. | 这就是说你可以在Python(或第三方库)任何用到文件的地方使用"HttpResponse"实例。 | 翻译 | ||
| 43#翻译 | For an example of how that works, let's take a look at producing CSV with Django. | 下面将用 Django 生成 CSV 文件为例,说明它的工作原理。 | 翻译 | ||
| 45#翻译 | Producing CSV | 生成 CSV 文件 | 翻译 | ||
| 47#翻译 | CSV is a simple data format usually used by spreadsheet software. | CSV 是一种简单的数据格式,通常为电子表格软件所使用。 | 翻译 | ||
| 48#翻译 | It's basically a series of table rows, with each cell in the row separated by a comma (CSV stands for <emphasis>comma-separated values</emphasis> ). For example, here's some data on unruly airline passengers in CSV format: | 它主要是由一系列的表格行组成,每行中单元格之间使用逗号(CSV 是 <emphasis>逗号分隔数值(comma-separated values)</emphasis> 的缩写)隔开。例如,下面是CSV格式的“不守规矩”的飞机乘客表。 | 翻译 | ||
| 51#翻译 | Note | 备注 | 翻译 | ||
| 53#翻译 | The preceding listing contains real numbers! | 前面的列表包含真实数据。 | 翻译 | ||
| 54#翻译 | They come from the U.S. | 这些数据来自美国 | 翻译 | ||
| 55#翻译 | Federal Aviation Administration. | 联邦航空管理局。 | 翻译 | ||
| 57#翻译 | Though CSV looks simple, its formatting details haven't been universally agreed upon. | CSV格式尽管看起来简单,却是全球通用的。 | 翻译 | ||
| 58#翻译 | Different pieces of software produce and consume different variants of CSV, making it a bit tricky to use. | 但是不同的软件会生成和使用不同的 CSV 的变种,在使用上会有一些不便。 | 翻译 | ||
| 59#翻译 | Luckily, Python comes with a standard CSV library, <literal>csv</literal> , that is pretty much bulletproof. | 幸运的是, Python 使用的是标准 CSV 库, <literal>csv</literal> ,所以它更通用。 | 翻译 | ||
| 61#翻译 | Because the <literal>csv</literal> module operates on file-like objects, it's a snap to use an <literal>HttpResponse</literal> instead: | 因为 <literal>csv</literal> 模块操作的是类似文件的对象,所以可以使用 <literal>HttpResponse</literal> 替换: | 翻译 | ||
| 64#翻译 | The code and comments should be pretty clear, but a few things deserve special mention: | 代码和注释可以说是很清楚,但还有一些事情需要特别注意: | 翻译 | ||
| 66#翻译 | The response is given the <literal>text/csv</literal> MIME type (instead of the default <literal>text/html</literal> ). This tells browsers that the document is a CSV file. | 响应返回的是 <literal>text/csv</literal> MIME类型(而非默认的 <literal>text/html</literal> )。这会告诉浏览器,返回的文档是CSV文件。 | 翻译 | ||
| 68#翻译 | The response gets an additional <literal>Content-Disposition</literal> header, which contains the name of the CSV file. | 响应会有一个附加的 <literal>Content-Disposition</literal> 头部,它包含有CSV文件的文件名。 | 翻译 | ||
| 69#翻译 | This header (well, the attachment part) will instruct the browser to prompt for a location to save the file instead of just displaying it. | 这个头部(或者说,附加部分)会指示浏览器弹出对话框询问文件存放的位置(而不仅仅是显示)。 | 翻译 | ||
| 70#翻译 | This file name is arbitrary; call it whatever you want. | 这个文件名是任意的。 | 翻译 | ||
| 71#翻译 | It will be used by browsers in the Save As dialog. | 它会显示在浏览器的另存为对话框中。 | 翻译 | ||
| 73#翻译 | To assign a header on an <literal>HttpResponse</literal> , just treat the <literal>HttpResponse</literal> as a dictionary and set a key/value. | 要在<literal>HttpResponse</literal>指定头部信息,只需把<literal>HttpResponse</literal>当做字典使用就可以了。 | 翻译 | ||
| 75#翻译 | Hooking into the CSV-generation API is easy: | 与创建CSV的应用程序界面(API)挂接是很容易的: | 翻译 | ||
| 76#翻译 | just pass <literal>response</literal> as the first argument to <literal>csv.writer</literal> . The <literal>csv.writer</literal> function expects a file-like object, and <literal>HttpResponse</literal> objects fit the bill. | 只需将 <literal>response</literal> 作为第一个变量传递给 <literal>csv.writer</literal> 。 <literal>csv.writer</literal> 函数需要一个文件类的对象, <literal>HttpResponse</literal> 正好能达成这个目的。 | 翻译 | ||
| 78#翻译 | For each row in your CSV file, call <literal>writer.writerow</literal> , passing it an iterable object such as a list or tuple. | 调用 <literal>writer.writerow</literal> ,并且传递给它一个类似 list 或者 tuple 的可迭代对象,就可以在 CSV 文件中写入一行。 | 翻译 | ||
| 80#翻译 | The CSV module takes care of quoting for you, so you don't have to worry about escaping strings with quotes or commas in them. | CSV 模块考虑到了引用的问题,所以您不用担心逸出字符串中引号和逗号。 | 翻译 | ||
| 81#翻译 | Just pass information to <literal>writerow()</literal> , and it will do the right thing. | 只要把信息传递给 <literal>writerow()</literal> ,它会处理好所有的事情。 | 翻译 | ||
| 83#翻译 | This is the general pattern you'll use any time you need to return non-HTML content: | 在任何需要返回非 HTML 内容的时候,都需要经过以下几步: | 翻译 | ||
| 84#翻译 | create an <literal>HttpResponse</literal> response object (with a special MIME type), pass it to something expecting a file, and then return the response. | 创建一个 <literal>HttpResponse</literal> 响应对象(需要指定特殊的 MIME 类型),它它传给需要处理文件的函数,然后返回这个响应对象。 | 翻译 | ||
| 86#翻译 | Let's look at a few more examples. | 下面是一些其它的例子。 | 翻译 | ||
| 88#翻译 | Generating PDFs | 生成 PDF 文件 | 翻译 | ||
| 90#翻译 | Portable Document Format (PDF) is a format developed by Adobe that's used to represent printable documents, complete with pixel-perfect formatting, embedded fonts, and 2D vector graphics. | 便携文档格式 (PDF) 是由 Adobe 开发的格式,主要用于呈现可打印的文档,其中包含有 pixel-perfect 格式,嵌入字体以及2D矢量图像。 | 翻译 | ||
| 91#翻译 | You can think of a PDF document as the digital equivalent of a printed document; indeed, PDFs are often used in distributing documents for the purpose of printing them. | 你可以把PDF文档理解为可打印文档的数字表达形式,而事实上,大多数分发文档采用PDF格式也就是为了打印。 | 翻译 | ||
| 93#翻译 | You can easily generate PDFs with Python and Django thanks to the excellent open source ReportLab library (<reference name="http://www.reportlab.org/rl_toolkit.html" refuri="http://www.reportlab.org/rl_toolkit.html">http://www.reportlab.org/rl_toolkit.html</reference>). | 你可以方便的使用 Python 和 Django 生成 PDF 文档,这要归功于一个出色的开源库, ReportLab (<reference name="http://www.reportlab.org/rl_toolkit.html" refuri="http://www.reportlab.org/rl_toolkit.html">http://www.reportlab.org/rl_toolkit.html</reference>) 。 | 翻译 | ||
| 94#翻译 | The advantage of generating PDF files dynamically is that you can create customized PDFs for different purposes say, for different users or different pieces of content. | 动态生成 PDF 文件的好处是,在不同的情况下,根据不同的用户或者不同的内容,可以按需生成不同的 PDF 文件。 | 翻译 | ||
| 96#翻译 | For example, your humble authors used Django and ReportLab at KUSports.com to generate customized, printer-ready NCAA tournament brackets. | 下面的例子是使用 Django 和 ReportLab 在 KUSports.com 上生成个性化的可打印的 NCAA 赛程表 (tournament brackets) 。 | 翻译 | ||
| 98#翻译 | Installing ReportLab | 安装 ReportLab | 翻译 | ||
| 100#翻译 | Before you do any PDF generation, however, you'll need to install ReportLab. | 在生成 PDF 文件之前,需要安装 ReportLab 库。这通常是个很简单的过程: | 翻译 | ||
| 101#翻译 | Its usually simple: | 很简单: | 翻译 | ||
| 102#翻译 | just download and install the library from <reference name="http://www.reportlab.org/downloads.html" refuri="http://www.reportlab.org/downloads.html">http://www.reportlab.org/downloads.html</reference>. | 只需从<reference name="http://www.reportlab.org/downloads.html" refuri="http://www.reportlab.org/downloads.html">http://www.reportlab.org/downloads.html</reference>下载然后安装。 | 翻译 | ||
| 104#翻译 | Note | 注意 | 翻译 | ||
| 106#翻译 | If you're using a modern Linux distribution, you might want to check your package management utility before installing ReportLab. | 如果使用的是一些新的 Linux 发行版,则在安装前可以先检查包管理软件。 | 翻译 | ||
| 107#翻译 | Most package repositories have added ReportLab. | 多数软件包仓库中都加入了 ReportLab 。 | 翻译 | ||
| 109#翻译 | For example, if you're using Ubuntu, a simple <literal>apt-get install python-reportlab</literal> will do the trick nicely. | 比如,如果使用Ubuntu 发行版,只需要简单的 <literal>apt-get install python-reportlab</literal> 一行命令即可完成安装。 | 翻译 | ||
| 111#翻译 | The user guide (naturally available only as a PDF file) at <reference name="http://www.reportlab.org/rsrc/userguide.pdf" refuri="http://www.reportlab.org/rsrc/userguide.pdf">http://www.reportlab.org/rsrc/userguide.pdf</reference> has additional installation instructions. | 使用手册(原始的只有 PDF 格式)可以从 <reference name="http://www.reportlab.org/rsrc/userguide.pdf" refuri="http://www.reportlab.org/rsrc/userguide.pdf">http://www.reportlab.org/rsrc/userguide.pdf</reference> 下载,其中包含有一些其它的安装指南。 | 翻译 | ||
| 113#翻译 | Test your installation by importing it in the Python interactive interpreter: | 在 Python 交互环境中导入这个软件包以检查安装是否成功。 | 翻译 | ||
| 116#翻译 | If that command doesn't raise any errors, the installation worked. | 如果刚才那条命令没有出现任何错误,则表明安装成功。 | 翻译 | ||
| 118#翻译 | Writing Your View | 编写视图 | 翻译 | ||
| 120#翻译 | Like CSV, generating PDFs dynamically with Django is easy because the ReportLab API acts on file-like objects. | 和 CSV 类似,由 Django 动态生成 PDF 文件很简单,因为 ReportLab API 同样可以使用类似文件对象。 | 翻译 | ||
| 122#翻译 | Here's a Hello World example: | 下面是一个 Hello World 的示例: | 翻译 | ||
| 125#翻译 | A few notes are in order: | 需要注意以下几点: | 翻译 | ||
| 127#翻译 | Here we use the <literal>application/pdf</literal> MIME type. | 这里我们使用的 MIME 类型是 <literal>application/pdf</literal> 。这会告诉浏览器这个文档是一个 PDF 文档,而不是 HTML 文档。 | 翻译 | ||
| 128#翻译 | This tells browsers that the document is a PDF file, rather than an HTML file. | 这会通知浏览器文档时PDF文件而不是HTML文件。 | 翻译 | ||
| 129#翻译 | If you leave off this information, browsers will probably interpret the response as HTML, which will result in scary gobbledygook in the browser window. | 如果忽略了这个参数,浏览器可能会把这个文件看成 HTML 文档,这会使浏览器的窗口中出现很奇怪的文字。 | 翻译 | ||
| 131#翻译 | Hooking into the ReportLab API is easy: | 使用 ReportLab 的 API 很简单: | 翻译 | ||
| 132#翻译 | just pass <literal>response</literal> as the first argument to <literal>canvas.Canvas</literal> . The <literal>Canvas</literal> class expects a file-like object, and <literal>HttpResponse</literal> objects fit the bill. | 只需要将 <literal>response</literal> 对象作为 <literal>canvas.Canvas</literal> 的第一个参数传入。 | 翻译 | ||
| 134#翻译 | All subsequent PDF-generation methods are called on the PDF object (in this case, <literal>p</literal> ), not on <literal>response</literal> . | 所有后续的 PDF 生成方法需要由 PDF 对象调用(在本例中是 <literal>p</literal> ),而不是 <literal>response</literal> 对象。 | 翻译 | ||
| 136#翻译 | Finally, it's important to call <literal>showPage()</literal> and <literal>save()</literal> on the PDF file or else, you'll end up with a corrupted PDF file. | 最后需要对 PDF 文件调用 <literal>showPage()</literal> 和 <literal>save()</literal> 方法(否则你会得到一个损坏的 PDF 文件)。 | 翻译 | ||
| 138#翻译 | Complex PDFs | 复杂的 PDF 文件 | 翻译 | ||
| 140#翻译 | If you're creating a complex PDF document (or any large data blob), consider using the <literal>cStringIO</literal> library as a temporary holding place for your PDF file. | 如果您在创建一个复杂的 PDF 文档(或者任何较大的数据块),请使用 <literal>cStringIO</literal> 库存放临时生成的 PDF 文件。 | 翻译 | ||
| 141#翻译 | The <literal>cStringIO</literal> library provides a file-like object interface that is written in C for maximum efficiency. | <literal>cStringIO</literal> 提供了一个用 C 编写的类似文件对象的接口,从而可以使系统的效率最高。 | 翻译 | ||
| 143#翻译 | Here's the previous Hello World example rewritten to use <literal>cStringIO</literal> : | 下面是使用 <literal>cStringIO</literal> 重写的 Hello World 例子: | 翻译 | ||
| 146#翻译 | Other Possibilities | 其它的可能性 | 翻译 | ||
| 148#翻译 | There's a whole host of other types of content you can generate in Python. | 使用 Python 可以生成许多其它类型的内容。 | 翻译 | ||
| 149#翻译 | Here are a few more ideas and some pointers to libraries you could use to implement them: | 下面介绍的是一些其它的想法和一些可以用以实现它们的库。 | 翻译 | ||
| 151#翻译 | <emphasis>ZIP files</emphasis> : Python's standard library ships with the <literal>zipfile</literal> module, which can both read and write compressed ZIP files. | <emphasis>ZIP 文件</emphasis> :Python 标准库中包含有 <literal>zipfile</literal> 模块,它可以读和写压缩的 ZIP 文件。 | 翻译 | ||
| 152#翻译 | You could use it to provide on-demand archives of a bunch of files, or perhaps compress large documents when requested. | 它可以用于按需生成一些文件的压缩包,或者在需要时压缩大的文档。 | 翻译 | ||
| 153#翻译 | You could similarly produce TAR files using the standard library's <literal>tarfile</literal> module. | 如果是 TAR 文件则可以使用标准库 <literal>tarfile</literal> 模块。 | 翻译 | ||
| 155#翻译 | <emphasis>Dynamic images</emphasis> : The Python Imaging Library (PIL; <reference name="http://www.pythonware.com/products/pil/" refuri="http://www.pythonware.com/products/pil/">http://www.pythonware.com/products/pil/</reference>) is a fantastic toolkit for producing images (PNG, JPEG, GIF, and a whole lot more). | <emphasis>动态图片</emphasis> : Python 图片处理库 (PIL; <reference name="http://www.pythonware.com/products/pil/" refuri="http://www.pythonware.com/products/pil/">http://www.pythonware.com/products/pil/</reference>) 是极好的生成图片(PNG, JPEG, GIF 以及其它许多格式)的工具。 | 翻译 | ||
| 156#翻译 | You could use it to automatically scale down images into thumbnails, composite multiple images into a single frame, or even do Web-based image processing. | 它可以用于自动为图片生成缩略图,将多张图片压缩到单独的框架中,或者是做基于 Web 的图片处理。 | 翻译 | ||
| 158#翻译 | <emphasis>Plots and charts</emphasis> : There are a number of powerful Python plotting and charting libraries you could use to produce on-demand maps, charts, plots, and graphs. | <emphasis>图表</emphasis> : Python 有许多出色并且强大的图表库用以绘制图表,按需地图,表格等。 | 翻译 | ||
| 159#翻译 | We can't possibly list them all, so here are a couple of the highlights: | 我们不可能将它们全部列出,所以下面列出的是个中的翘楚。 | 翻译 | ||
| 161#翻译 | <literal>matplotlib</literal> (<reference name="http://matplotlib.sourceforge.net/" refuri="http://matplotlib.sourceforge.net/">http://matplotlib.sourceforge.net/</reference>) can be used to produce the type of high-quality plots usually generated with MatLab or Mathematica. | <literal>matplotlib</literal> (<reference name="http://matplotlib.sourceforge.net/" refuri="http://matplotlib.sourceforge.net/">http://matplotlib.sourceforge.net/</reference>) 可以用于生成通常是由 matlab 或者 Mathematica 生成的高质量图表。 | 翻译 | ||
| 163#翻译 | <literal>pygraphviz</literal> (<reference name="http://networkx.lanl.gov/pygraphviz/" refuri="http://networkx.lanl.gov/pygraphviz/">http://networkx.lanl.gov/pygraphviz/</reference>), an interface to the Graphviz graph layout toolkit (<reference name="http://graphviz.org/" refuri="http://graphviz.org/">http://graphviz.org/</reference>), can be used for generating structured diagrams of graphs and networks. | <literal>pygraphviz</literal> (<reference name="https://networkx.lanl.gov/wiki/pygraphviz" refuri="https://networkx.lanl.gov/wiki/pygraphviz">https://networkx.lanl.gov/wiki/pygraphviz</reference>) 是一个 Graphviz 图形布局的工具 (<reference name="http://graphviz.org/" refuri="http://graphviz.org/">http://graphviz.org/</reference>) 的 Python 接口,可以用于生成结构化的图表和网络。 | 翻译 | ||
| 165#翻译 | In general, any Python library capable of writing to a file can be hooked into Django. | 总之,所有可以写文件的库都可以与 Django 同时使用。 | 翻译 | ||
| 166#翻译 | The possibilities are immense. | 可选的范围很大。 | 翻译 | ||
| 168#翻译 | Now that we've looked at the basics of generating non-HTML content, let's step up a level of abstraction. | 我们已经了解了生成“非HTML”内容的基本知识,让我们进一步总结一下。 | 翻译 | ||
| 169#翻译 | Django ships with some pretty nifty built-in tools for generating some common types of non-HTML content. | Django拥有很多用以生成各类“非HTML”内容的内置工具。 | 翻译 | ||
| 171#翻译 | The Syndication Feed Framework | 内容聚合器应用框架 | 翻译 | ||
| 173#翻译 | Django comes with a high-level syndication-feed-generating framework that makes creating RSS and Atom feeds easy. | Django带来了一个高级的聚合生成框架,它使得创建RSS和Atom feeds变得非常容易。 | 翻译 | ||
| 175#翻译 | What's RSS? | 什么是RSS? | 翻译 | ||
| 176#翻译 | Whats Atom? | 什么是Atom? | 翻译 | ||
| 178#翻译 | RSS and Atom are both XML-based formats you can use to provide automatically updating feeds of your site's content. | RSS和Atom都是基于XML的格式,你可以用它来提供有关你站点内容的自动更新的feed。 | 翻译 | ||
| 179#翻译 | Read more about RSS at <reference name="http://www.whatisrss.com/" refuri="http://www.whatisrss.com/">http://www.whatisrss.com/</reference>, and get information on Atom at <reference name="http://www.atomenabled.org/" refuri="http://www.atomenabled.org/">http://www.atomenabled.org/</reference>. | 了解更多关于RSS的可以访问 <reference name="http://www.whatisrss.com/" refuri="http://www.whatisrss.com/">http://www.whatisrss.com/</reference>, 更多Atom的信息可以访问 <reference name="http://www.atomenabled.org/" refuri="http://www.atomenabled.org/">http://www.atomenabled.org/</reference>. | 翻译 | ||
| 181#翻译 | To create any syndication feed, all you have to do is write a short Python class. | 想创建一个聚合源(syndication feed),所需要做的只是写一个简短的Python类。 | 翻译 | ||
| 182#翻译 | You can create as many feeds as you want. | 你可以创建任意多的源(feed)。 | 翻译 | ||
| 184#翻译 | The high-level feed-generating framework is a view that's hooked to <literal>/feeds/</literal> by convention. | 高级feed生成框架是一个默认绑定到/feeds/的视图。 | 翻译 | ||
| 185#翻译 | Django uses the remainder of the URL (everything after <literal>/feeds/</literal> ) to determine which feed to return. | Django使用URL的其它部分(在/feeds/之后的任何东西)来决定输出哪个feed。 | 翻译 | ||
| 187#翻译 | To create a feed, you'll write a <literal>Feed</literal> class and point to it in your URLconf. | 要创建一个 sitemap,你只需要写一个 <literal>Feed</literal> 类然后配置你的URLconf指向它。 | 翻译 | ||
| 189#翻译 | Initialization | 初始化 | 翻译 | ||
| 191#翻译 | To activate syndication feeds on your Django site, add this URLconf: | 为了在您的Django站点中激活syndication feeds, 添加如下的 URLconf: | 翻译 | ||
| 194#翻译 | This line tells Django to use the RSS framework to handle all URLs starting with <literal>"feeds/"</literal> . (You can change that <literal>"feeds/"</literal> prefix to fit your own needs.) | 这一行告诉Django使用RSS框架处理所有的以 <literal>"feeds/"</literal> 开头的URL。 ( 你可以修改 <literal>"feeds/"</literal> 前缀以满足您自己的要求.。) | 翻译 | ||
| 196#翻译 | This URLconf line has an extra argument: | URLConf里有一个额外参数: | 翻译 | ||
| 197#翻译 | <literal>{'feed_dict': | {'feed_dict': | 翻译 | ||
| 198#翻译 | feeds}</literal> . Use this extra argument to pass the syndication framework the feeds that should be published under that URL. | feeds}</literal>,这个参数可以把对应URL需要发布的feed内容传递给 syndication framework | 翻译 | ||
| 200#翻译 | Specifically, <literal>feed_dict</literal> should be a dictionary that maps a feed's slug (short URL label) to its <literal>Feed</literal> class. | 特别的,feed_dict应该是一个映射feed的slug(简短URL标签)的字典。 | 翻译 | ||
| 201#翻译 | You can define the <literal>feed_dict</literal> in the URLconf itself. | 你可以自定义<literal>feed_dict</literal>。 | 翻译 | ||
| 202#翻译 | Here's a full example URLconf: | 这里是一个完整的例子。 | 翻译 | ||
| 205#翻译 | The preceding example registers two feeds: | 前面的例子注册了两个feed: | 翻译 | ||
| 207#翻译 | The feed represented by <literal>LatestEntries</literal> will live at <literal>feeds/latest/</literal> . | <literal>LatestEntries``表示的内容将对应到``feeds/latest/</literal> . | 翻译 | ||
| 209#翻译 | The feed represented by <literal>LatestEntriesByCategory</literal> will live at <literal>feeds/categories/</literal> . | <literal>LatestEntriesByCategory``的内容将对应到 ``feeds/categories/</literal> . | 翻译 | ||
| 211#翻译 | Once that's set up, youll need to define the <literal>Feed</literal> classes themselves. | 以上的设定完成之后,接下来需要自己定义 <literal>Feed</literal> 类。 | 翻译 | ||
| 213#翻译 | A <literal>Feed</literal> class is a simple Python class that represents a syndication feed. | 一个 <literal>Feed</literal> 类是一个简单的python类,用来表示一个聚合feed。 | 翻译 | ||
| 214#翻译 | A feed can be simple (e.g., a site news feed, or a basic feed displaying the latest entries of a blog) or more complex (e.g., a feed displaying all the blog entries in a particular category, where the category is variable). | 一个feed可能是简单的 (例如一个站点新闻feed,或者最基本的,显示一个blog的最新条目),也可能更加复杂(例如一个显示blog某一类别下所有条目的feed)。 | 翻译 | ||
| 216#翻译 | <literal>Feed</literal> classes must subclass <literal>django.contrib.syndication.feeds.Feed</literal> . They can live anywhere in your code tree. | Feed类必须继承django.contrib.syndication.feeds.Feed,它们可以位于你代码树的任何位置。 | 翻译 | ||
| 218#翻译 | A Simple Feed | 一个简单的Feed | 翻译 | ||
| 220#翻译 | This simple example describes a feed of the latest five blog entries for a given blog: | 这是一个简单的返回指定博客最新五条记录的feed。 | 翻译 | ||
| 223#翻译 | The important things to notice here are as follows: | 要注意的重要的事情如下所示: | 翻译 | ||
| 225#翻译 | The class subclasses <literal>django.contrib.syndication.feeds.Feed</literal> . | 子类 <literal>django.contrib.syndication.feeds.Feed</literal>。 | 翻译 | ||
| 227#翻译 | <literal>title</literal> , <literal>link</literal> , and <literal>description</literal> correspond to the standard RSS <literal><title></literal> , <literal><link></literal> , and <literal><description></literal> elements, respectively. | <literal>title</literal> , <literal>link</literal> , 和 <literal>description</literal> 对应一个标准 RSS 里的 <literal><title></literal> , <literal><link></literal> , 和 <literal><description></literal> 标签. | 翻译 | ||
| 229#翻译 | <literal>items()</literal> is simply a method that returns a list of objects that should be included in the feed as <literal><item></literal> elements. | <literal>items()</literal> 是一个方法,返回一个用以包含在feed里的 <literal>item</literal> 元素里的列表。 | 翻译 | ||
| 230#翻译 | Although this example returns <literal>Entry</literal> objects using Django's database API, <literal>items()</literal> doesn't have to return model instances. | 虽然例子里用Django database API返回的<literal>Entry</literal>对象,<literal>items()</literal>不一定必须返回 model的实例。 | 翻译 | ||
| 232#翻译 | There's just one more step. | 还有一个步骤。 | 翻译 | ||
| 233#翻译 | In an RSS feed, each <literal><item></literal> has a <literal><title></literal> , <literal><link></literal> , and <literal><description></literal> . We need to tell the framework what data to put into those elements. | 在一个RSS feed里,每个(item)有一个(title),(link)和(description),我们需要告诉框架 把数据放到这些元素中。 | 翻译 | ||
| 235#翻译 | To specify the contents of <literal><title></literal> and <literal><description></literal> , create Django templates called <literal>feeds/latest_title.html</literal> and <literal>feeds/latest_description.html</literal> , where <literal>latest</literal> is the <literal>slug</literal> specified in the URLconf for the given feed. | 如果要指定 <literal></literal> 和 <literal></literal> ,可以建立一个Django模板,名字叫 <literal>feeds/latest_title.html</literal> 和 <literal>feeds/latest_description.html</literal> ,后者是URLConf里为对应feed指定的 <literal>slug</literal> 。 | 翻译 | ||
| 236#翻译 | Note that the <literal>.html</literal> extension is required. | 注意<literal>.html</literal>后缀是必须的。 | 翻译 | ||
| 238#翻译 | The RSS system renders that template for each item, passing it two template context variables: | RSS系统模板渲染每一个条目,需要给传递2个参数给模板上下文变量: | 翻译 | ||
| 240#翻译 | <literal>obj</literal> : The current object (one of whichever objects you returned in <literal>items()</literal> ). | <literal>obj</literal> : 当前对象 ( 返回到 <literal>items()</literal> 任意对象之一 )。 | 翻译 | ||
| 242#翻译 | <literal>site</literal> : A <literal>django.models.core.sites.Site</literal> object representing the current site. | <literal>site</literal> : 一个表示当前站点的 <literal>django.models.core.sites.Site</literal> 对象。 | 翻译 | ||
| 243#翻译 | This is useful for <literal>{{ site.domain }}</literal> or <literal>{{ site.name }}</literal> . | 这对于 <literal>{{ site.domain }}</literal> 或者 <literal>{{ site.name }}</literal> 很有用。 | 翻译 | ||
| 245#翻译 | If you don't create a template for either the title or description, the framework will use the template <literal>"{{ obj }}"</literal> by default that is, the normal string representation of the object. | 如果你在创建模板的时候,没有指明标题或者描述信息,框架会默认使用 <literal>"{{ obj }}"</literal> ,对象的字符串表示。 | 翻译 | ||
| 246#翻译 | (For model objects, this will be the <literal>__unicode__()</literal> method. | (对于模型对象,就是指<literal>__unicode__()</literal>方法。 | 翻译 | ||
| 248#翻译 | You can also change the names of these two templates by specifying <literal>title_template</literal> and <literal>description_template</literal> as attributes of your <literal>Feed</literal> class. | 你也可以通过修改 <literal>Feed</literal> 类中的两个属性 <literal>title_template</literal> 和 <literal>description_template</literal> 来改变这两个模板的名字。 | 翻译 | ||
| 250#翻译 | To specify the contents of <literal><link></literal> , you have two options. | 你有两种方法来指定 <literal><link></literal> 的内容。 | 翻译 | ||
| 251#翻译 | For each item in <literal>items()</literal> , Django first tries executing a <literal>get_absolute_url()</literal> method on that object. | Django 首先执行 <literal>items()</literal> 中每一项的 <literal>get_absolute_url()</literal> 方法。 | 翻译 | ||
| 252#翻译 | If that method doesn't exist, it tries calling a method <literal>item_link()</literal> in the <literal>Feed</literal> class, passing it a single parameter, <literal>item</literal> , which is the object itself. | 如果该方法不存在,就会尝试执行 <literal>Feed</literal> 类中的 <literal>item_link()</literal> 方法,并将自身作为 <literal>item</literal> 参数传递进去。 | 翻译 | ||
| 254#翻译 | Both <literal>get_absolute_url()</literal> and <literal>item_link()</literal> should return the item's URL as a normal Python string. | <literal>get_absolute_url()</literal> 和 <literal>item_link()</literal> 都应该以Python字符串形式返回URL。 | 翻译 | ||
| 256#翻译 | For the previous <literal>LatestEntries</literal> example, we could have very simple feed templates. | 对于前面提到的 <literal>LatestEntries</literal> 例子,我们可以实现一个简单的feed模板。 | 翻译 | ||
| 257#翻译 | <literal>latest_title.html</literal> contains: | <literal>latest_title.html</literal> 包括: | 翻译 | ||
| 260#翻译 | and <literal>latest_description.html</literal> contains: | 然后 <literal>latest_description.html</literal> 包含: | 翻译 | ||
| 263#翻译 | It's almost <emphasis>too</emphasis> easy | 这真是 <emphasis>太</emphasis> 简单了! | 翻译 | ||
| 265#翻译 | A More Complex Feed | 一个更复杂的Feed | 翻译 | ||
| 267#翻译 | The framework also supports more complex feeds, via parameters. | 框架通过参数支持更加复杂的feeds。 | 翻译 | ||
| 269#翻译 | For example, say your blog offers an RSS feed for every distinct tag you've used to categorize your entries. | 例如,假设你的blog提供一个返回所有你使用过的tag的RSS feed。 | 翻译 | ||
| 270#翻译 | It would be silly to create a separate <literal>Feed</literal> class for each tag; that would violate the Don't Repeat Yourself (DRY) principle and would couple data to programming logic. | 如果为每一个单独的tag建立一个 <literal>Feed</literal> 类就显得很不明智。这违背了“不做重复工作”的原则,并且带来了代码耦合。 | 翻译 | ||
| 272#翻译 | Instead, the syndication framework lets you make generic feeds that return items based on information in the feed's URL. | 取而代之的方法是,使用聚合框架来产生一个通用的源,使其可以根据feeds URL返回相应的信息。 | 翻译 | ||
| 274#翻译 | Your tag-specific feeds could use URLs like this: | 你的feed可以使用这样的URL: | 翻译 | ||
| 276#翻译 | <literal>http://example.com/feeds/tags/python/</literal> : Returns recent entries tagged with python | <literal>http://example.com/feeds/tags/python/</literal>: 返回tag为Python的最新条目。 | 翻译 | ||
| 278#翻译 | <literal>http://example.com/feeds/tags/cats/</literal> : Returns recent entries tagged with cats | <literal>http://example.com/feeds/tags/cats/</literal>: 返回tag为猫的最新条目。 | 翻译 | ||
| 280#翻译 | The slug here is <literal>"tags"</literal> . The syndication framework sees the extra URL bits after the slug <literal>'python'</literal> and <literal>'cats'</literal> and gives you a hook to tell it what those URL bits mean and how they should influence which items get published in the feed. | 不一样的的那一部分是 <literal>"tags"</literal>。聚合框架检查<literal>'python'</literal>和<literal>'cats'</literal>之后的URL参数,你可以通知框架这个参数的意义以及它如何影响feed中发布的条目。 | 翻译 | ||
| 282#翻译 | An example makes this clear. | 举个例子会澄清一切。 | 翻译 | ||
| 283#翻译 | Here's the code for these tag-specific feeds: | 下面是拥有特定tag的feed: | 翻译 | ||
| 286#翻译 | Here's the basic algorithm of the RSS framework, given this class and a request to the URL <literal>/feeds/tags/python/</literal> : | 以下是RSS框架的基本算法,我们假设通过URL <literal>/feeds/tags/python/</literal> 来访问这个类: | 翻译 | ||
| 288#翻译 | The framework gets the URL <literal>/feeds/tags/python/</literal> and notices there's an extra bit of URL after the slug. | 框架获得了URL <literal>/feeds/tags/python/</literal> 并且注意到URL中的slug部分后面含有更多的信息。 | 翻译 | ||
| 289#翻译 | It splits that remaining string by the slash character (<literal>"/"</literal> ) and calls the <literal>Feed</literal> class's <literal>get_object()</literal> method, passing it the bits. | 它将斜杠(<literal>"/"</literal> )作为分隔符,把剩余的字符串分割开作为参数,调用 <literal>Feed</literal> 类的 <literal>get_object()</literal> 方法。 | 翻译 | ||
| 291#翻译 | In this case, bits is <literal>['python']</literal> . For a request to <literal>/feeds/tags/python/django/</literal> , bits would be <literal>['python', 'django']</literal> . | 在这个例子中,添加的信息是 <literal>['python']</literal> 。对于 <literal>/feeds/tags/python/django/</literal> 的一个URL请求, 这些信息就是 <literal>['python', 'django']</literal> 。 | 翻译 | ||
| 293#翻译 | <literal>get_object()</literal> is responsible for retrieving the given <literal>Tag</literal> object, from the given <literal>bits</literal> . | <literal>get_object()</literal> 就根据给定的 <literal>bits</literal> 值来返回区域信息。 | 翻译 | ||
| 295#翻译 | In this case, it uses the Django database API to retrieve the <literal>Tag</literal> . Note that <literal>get_object()</literal> should raise <literal>django.core.exceptions.ObjectDoesNotExist</literal> if given invalid parameters. | 在这个例子中,使用Django的数据库API来取回<literal>Tag</literal>。注意如果参数不合法<literal>get_objext()</literal>应该抛出<literal>django.core.exceptions.ObjectDoesNotExist</literal>。 | 翻译 | ||
| 296#翻译 | There's no <literal>try</literal> /<literal>except</literal> around the <literal>Tag.objects.get()</literal> call, because it's not necessary. | 在 <literal>Tag.objects.get()</literal> 调用中没有出现 <literal>try</literal>和<literal>except</literal> 代码块,因为没有这个必要。 | 翻译 | ||
| 297#翻译 | That function raises <literal>Tag.DoesNotExist</literal> on failure, and <literal>Tag.DoesNotExist</literal> is a subclass of <literal>ObjectDoesNotExist</literal> . Raising <literal>ObjectDoesNotExist</literal> in <literal>get_object()</literal> tells Django to produce a 404 error for that request. | 函数在出错时抛出 <literal>Tag.DoesNotExist</literal> 异常,而 <literal>Tag.DoesNotExist</literal> 是 <literal>ObjectDoesNotExist</literal> 异常的一个子类。在<literal>get_object()</literal>里抛出<literal>ObjectDoesNotExist</literal>会通知Django显示404错误页面。 | 翻译 | ||
| 299#翻译 | To generate the feed's <literal><title></literal> , <literal><link></literal> , and <literal><description></literal> , Django uses the <literal>title()</literal> , <literal>link()</literal> , and <literal>description()</literal> methods. | 为产生 <literal><title></literal> , <literal><link></literal> , 和 <literal><description></literal> 的feeds, Django使用 <literal>title()</literal> , <literal>link()</literal> , 和 <literal>description()</literal> 方法。 | 翻译 | ||
| 300#翻译 | In the previous example, they were simple string class attributes, but this example illustrates that they can be either strings <emphasis>or</emphasis> methods. | 在上面的例子中,它们都是简单的字符串类型的类属性,而这个例子表明,它们既可以是字符串, <emphasis>也可以是</emphasis> 方法。 | 翻译 | ||
| 301#翻译 | For each of <literal>title</literal> , <literal>link</literal> , and <literal>description</literal> , Django follows this algorithm: | 对于每一个 <literal>title</literal> , <literal>link</literal> 和 <literal>description</literal> 的组合,Django使用以下的算法: | 翻译 | ||
| 303#翻译 | It tries to call a method, passing the <literal>obj</literal> argument, where <literal>obj</literal> is the object returned by <literal>get_object()</literal> . | 试图调用一个函数,并且以 <literal>get_object()</literal> 返回的对象<literal>obj</literal>作为参数。 | 翻译 | ||
| 305#翻译 | Failing that, it tries to call a method with no arguments. | 如果没有成功,则不带参数调用一个方法。 | 翻译 | ||
| 307#翻译 | Failing that, it uses the class attribute. | 还不成功,则使用类属性。 | 翻译 | ||
| 309#翻译 | Finally, note that <literal>items()</literal> in this example also takes the <literal>obj</literal> argument. | 最后,值得注意的是,这个例子中的 <literal>items()</literal>也使用 <literal>obj</literal> 参数。 | 翻译 | ||
| 310#翻译 | The algorithm for <literal>items</literal> is the same as described in the previous step first, it tries <literal>items(obj)</literal> , then <literal>items()</literal> , and then finally an <literal>items</literal> class attribute (which should be a list). | 对于 <literal>items</literal> 的算法就如同上面第一步所描述的那样,首先尝试 <literal>items(obj)</literal> , 然后是 <literal>items()</literal> ,最后是 <literal>items</literal> 类属性(必须是一个列表)。 | 翻译 | ||
| 312#翻译 | Full documentation of all the methods and attributes of the <literal>Feed</literal> classes is always available from the official Django documentation (<reference name="http://docs.djangoproject.com/en/dev/ref/contrib/syndication/" refuri="http://docs.djangoproject.com/en/dev/ref/contrib/syndication/">http://docs.djangoproject.com/en/dev/ref/contrib/syndication/</reference>). | <literal>Feed</literal> 类所有方法和属性的完整文档,请参考官方的Django文档 (<reference name="http://www.djangoproject.com/documentation/0.96/syndication_feeds/" refuri="http://www.djangoproject.com/documentation/0.96/syndication_feeds/">http://www.djangoproject.com/documentation/0.96/syndication_feeds/</reference>) 。 | 翻译 | ||
| 314#翻译 | Specifying the Type of Feed | 指定Feed的类型 | 翻译 | ||
| 316#翻译 | By default, the syndication framework produces RSS 2.0. | 默认情况下, 聚合框架生成RSS 2.0。 | 翻译 | ||
| 317#翻译 | To change that, add a <literal>feed_type</literal> attribute to your <literal>Feed</literal> class: | 要改变这样的情况需要在<literal>Feed</literal>类中添加一个<literal>feed_type</literal>属性。 | 翻译 | ||
| 320#翻译 | Note that you set <literal>feed_type</literal> to a class object, not an instance. | 注意你把 <literal>feed_type</literal> 赋值成一个类对象,而不是类实例。 | 翻译 | ||
| 321#翻译 | Currently available feed types are shown in Table 11-1. | 目前合法的Feed类型如表11-1所示。 | 翻译 | ||
| 323#翻译 | <table> | <table> | 翻译 | ||
| 324#翻译 | Table 11-1. | 表 11-1. | 翻译 | ||
| 325#翻译 | Feed Types | Feed 类型 | 翻译 | ||
| 327#翻译 | Feed Class | Feed 类 | 翻译 | ||
| 329#翻译 | Format | 类型 | 翻译 | ||
| 331#翻译 | <literal>django.utils.feedgenerator.Rss201rev2Feed</literal> | django.utils.feedgenerator.Rss201rev2Feed | 翻译 | ||
| 333#翻译 | RSS 2.01 (default) | RSS 2.01 (默认的) | 翻译 | ||
| 335#翻译 | <literal>django.utils.feedgenerator.RssUserland091Feed</literal> | django.utils.feedgenerator.RssUserland091Feed | 翻译 | ||
| 337#翻译 | RSS 0.91 | RSS 0.91 | 翻译 | ||
| 339#翻译 | <literal>django.utils.feedgenerator.Atom1Feed</literal> | django.utils.feedgenerator.Atom1Feed | 翻译 | ||
| 341#翻译 | Atom 1.0 | Atom 1.0 | 翻译 | ||
| 342#翻译 | </entry></row></tbody></tgroup></table><cnid>150 | 150 | 翻译 | ||
| 343#翻译 | Enclosures | 闭包 | 翻译 | ||
| 345#翻译 | To specify enclosures (i.e., media resources associated with a feed item such as MP3 podcast feeds), use the <literal>item_enclosure_url</literal> , <literal>item_enclosure_length</literal> , and <literal>item_enclosure_mime_type</literal> hooks, for example: | 为了指定闭包(例如,与feed项比方说MP3 feeds相关联的媒体资源信息),使用 <literal>item_enclosure_url</literal> , <literal>item_enclosure_length</literal> , 以及 <literal>item_enclosure_mime_type</literal> ,比如 | 翻译 | ||
| 348#翻译 | This assumes, of course, that you've created a <literal>Song</literal> object with <literal>song_url</literal> and <literal>song_length</literal> (i.e., the size in bytes) fields. | 当然,你首先要创建一个包含有 <literal>song_url</literal> 和 <literal>song_length</literal> (比如按照字节计算的长度)域的 <literal>Song</literal> 对象。 | 翻译 | ||
| 350#翻译 | Language | 语言 | 翻译 | ||
| 352#翻译 | Feeds created by the syndication framework automatically include the appropriate <literal><language></literal> tag (RSS 2.0) or <literal>xml:lang</literal> attribute (Atom). | 聚合框架自动创建的Feed包含适当的 <literal></literal> 标签(RSS 2.0) 或 <literal>xml:lang</literal> 属性(Atom)。 | 翻译 | ||
| 353#翻译 | This comes directly from your <literal>LANGUAGE_CODE</literal> setting. | 它直接来自于您的 LANGUAGE_CODE 设置。 | 翻译 | ||
| 355#翻译 | URLs | URLs | 翻译 | ||
| 357#翻译 | The <literal>link</literal> method/attribute can return either an absolute URL (e.g., <literal>"/blog/"</literal> ) or a URL with the fully qualified domain and protocol (e.g., <literal>"http://www.example.com/blog/"</literal> ). If <literal>link</literal> doesn't return the domain, the syndication framework will insert the domain of the current site, according to your <literal>SITE_ID</literal> setting. | <literal>link</literal> 方法/属性可以返回绝对URL的形式(例如, <literal>"/blog/"</literal> )或者指定协议和域名的URL的形式返回(例如 <literal>"http://www.example.com/blog/"</literal> )。如果 <literal>link</literal> 没有返回域名,聚合框架会根据 <literal>SITE_ID</literal> 设置,自动的插入当前站点的域信息。 | 翻译 | ||
| 358#翻译 | (See Chapter 16 for more on <literal>SITE_ID</literal> and the sites framework.) | (参阅第16章以获得更多有关<literal>SITE_ID</literal>和框架的信息。) | 翻译 | ||
| 360#翻译 | Atom feeds require a <literal><link rel="self"></literal> that defines the feed's current location. | Atom feeds需要 <literal><link rel="self"></literal> 指明feeds现在的位置。 | 翻译 | ||
| 361#翻译 | The syndication framework populates this automatically. | 聚合框架会自动完成这项工作。 | 翻译 | ||
| 363#翻译 | Publishing Atom and RSS Feeds in Tandem | 同时发布Atom and RSS | 翻译 | ||
| 365#翻译 | Some developers like to make available both Atom <emphasis>and</emphasis> RSS versions of their feeds. | 一些开发人员想 <emphasis>同时</emphasis> 支持Atom和RSS。 | 翻译 | ||
| 366#翻译 | That's easy to do with Django: | 这在Django中很容易实现: | 翻译 | ||
| 367#翻译 | just create a subclass of your <literal>feed</literal> class and set the <literal>feed_type</literal> to something different. | 只需创建一个你的 <literal>feed</literal> 类的子类,修改 <literal>feed_type</literal>。 | 翻译 | ||
| 368#翻译 | Then update your URLconf to add the extra versions. | 然后更新URLconf内容。 | 翻译 | ||
| 369#翻译 | Here's a full example: | 下面是一个完整的例子: | 翻译 | ||
| 372#翻译 | And here's the accompanying URLconf: | 这是与之相对应那个的URLconf: | 翻译 | ||
| 375#翻译 | The Sitemap Framework | Sitemap 框架 | 翻译 | ||
| 377#翻译 | A <emphasis>sitemap</emphasis> is an XML file on your Web site that tells search engine indexers how frequently your pages change and how important certain pages are in relation to other pages on your site. | <emphasis>sitemap</emphasis> 是你服务器上的一个XML文件,它告诉搜索引擎你的页面的更新频率和某些页面相对于其它页面的重要性。 | 翻译 | ||
| 378#翻译 | This information helps search engines index your site. | 这个信息会帮助搜索引擎索引你的网站。 | 翻译 | ||
| 380#翻译 | For example, here's a piece of the sitemap for Django's Web site (<reference name="http://www.djangoproject.com/sitemap.xml" refuri="http://www.djangoproject.com/sitemap.xml">http://www.djangoproject.com/sitemap.xml</reference>): | 例如,这是 Django 网站(<reference name="http://www.djangoproject.com/sitemap.xml" refuri="http://www.djangoproject.com/sitemap.xml">http://www.djangoproject.com/sitemap.xml</reference>)sitemap的一部分: | 翻译 | ||
| 383#翻译 | For more on sitemaps, see <reference name="http://www.sitemaps.org/" refuri="http://www.sitemaps.org/">http://www.sitemaps.org/</reference>. | 需要了解更多有关 sitemaps 的信息, 请参见 <reference name="http://www.sitemaps.org/" refuri="http://www.sitemaps.org/">http://www.sitemaps.org/</reference>. | 翻译 | ||
| 385#翻译 | The Django sitemap framework automates the creation of this XML file by letting you express this information in Python code. | Django sitemap 框架允许你用 Python 代码来表述这些信息,从而自动创建这个XML文件。 | 翻译 | ||
| 386#翻译 | To create a sitemap, you just need to write a <literal>Sitemap</literal> class and point to it in your URLconf. | 要创建一个站点地图,你只需要写一个<literal> Sitemap</literal> 类,并且在URLconf中指向它。 | 翻译 | ||
| 388#翻译 | Installation | 安装 | 翻译 | ||
| 390#翻译 | To install the sitemap application, follow these steps: | 要安装 sitemap 应用程序, 按下面的步骤进行: | 翻译 | ||
| 392#翻译 | Add <literal>'django.contrib.sitemaps'</literal> to your <literal>INSTALLED_APPS</literal> setting. | 将 <literal>'django.contrib.sitemaps'</literal> 添加到您的 <literal>INSTALLED_APPS</literal> 设置中. | 翻译 | ||
| 394#翻译 | Make sure <literal>'django.template.loaders.app_directories.load_template_source'</literal> is in your <literal>TEMPLATE_LOADERS</literal> setting. | 确保 <literal>'django.template.loaders.app_directories.load_template_source'</literal> 在您的 <literal>TEMPLATE_LOADERS</literal> 设置中。 | 翻译 | ||
| 395#翻译 | It's in there by default, so you'll need to change this only if youve changed that setting. | 默认情况下它在那里,所以,你不需要做什么,除非你更改了那个设置。 | 翻译 | ||
| 397#翻译 | Make sure you've installed the sites framework (see Chapter 16). | 确定您已经安装了 sites 框架 (参见第16章). | 翻译 | ||
| 399#翻译 | Note | 注意 | 翻译 | ||
| 401#翻译 | The sitemap application doesn't install any database tables. | sitemap 应用程序没有安装任何数据库表。 | 翻译 | ||
| 402#翻译 | The only reason it needs to go into <literal>INSTALLED_APPS</literal> is so the <literal>load_template_source</literal> template loader can find the default templates. | 它需要加入到<literal>INSTALLED_APPS</literal>中的唯一原因是: 这样<literal>load_template_source</literal>模板加载器可以找到默认的模板。 | 翻译 | ||
| 404#翻译 | Initialization | 初始化 | 翻译 | ||
| 406#翻译 | To activate sitemap generation on your Django site, add this line to your URLconf: | 要在您的Django站点中激活sitemap生成, 请在您的 URLconf 中添加这一行: | 翻译 | ||
| 409#翻译 | This line tells Django to build a sitemap when a client accesses <literal>/sitemap.xml</literal> . Note that the dot character in <literal>sitemap.xml</literal> is escaped with a backslash, because dots have a special meaning in regular expressions. | 这行通知Django当客户端索取<literal>/sitemap.xml</literal>时创建sitemap。注意<literal>sitemap.xml</literal>中的"."被反斜杠转移了,因为它在正则表达式里有特殊含义。 | 翻译 | ||
| 411#翻译 | The name of the sitemap file is not important, but the location is. | sitemap文件的名字无关紧要,但是它在服务器上的位置却很重要。 | 翻译 | ||
| 412#翻译 | Search engines will only index links in your sitemap for the current URL level and below. | 搜索引擎只索引你的sitemap中当前URL级别及其以下级别的链接。 | 翻译 | ||
| 413#翻译 | For instance, if <literal>sitemap.xml</literal> lives in your root directory, it may reference any URL in your site. | 用一个实例来说,如果 <literal>sitemap.xml</literal> 位于你的根目录,那么它将引用任何的URL。 | 翻译 | ||
| 414#翻译 | However, if your sitemap lives at <literal>/content/sitemap.xml</literal> , it may only reference URLs that begin with <literal>/content/</literal> . | 然而,如果你的sitemap位于 <literal>/content/sitemap.xml</literal> ,那么它只引用以 <literal>/content/</literal> 打头的URL。 | 翻译 | ||
| 416#翻译 | The sitemap view takes an extra, required argument: | sitemap视图需要一个额外的必须的参数: | 翻译 | ||
| 417#翻译 | <literal>{'sitemaps': | {'sitemaps': | 翻译 | ||
| 418#翻译 | sitemaps}</literal> . <literal>sitemaps</literal> should be a dictionary that maps a short section label (e.g., <literal>blog</literal> or <literal>news</literal> ) to its <literal>Sitemap</literal> class (e.g., <literal>BlogSitemap</literal> or <literal>NewsSitemap</literal> ). It may also map to an <emphasis>instance</emphasis> of a <literal>Sitemap</literal> class (e.g., <literal>BlogSitemap(some_var)</literal> ). | sitemaps}。<literal>sitemap</literal>是把小段的标签(如<literal>blog</literal>或者<literal>news</literal>)映射到<literal>Sitemap</literal>(如<literal>BlogSitemap</literal>或者<literal>NewsSitemap</literal>)的字典。它也会映射到<emphasis>Sitemap</emphasis>的<literal>实例</literal>(如<literal>BlogSitemap(some_var)</literal>)。 | 翻译 | ||
| 420#翻译 | Sitemap Classes | Sitemap 类 | 翻译 | ||
| 422#翻译 | A <literal>Sitemap</literal> class is a simple Python class that represents a section of entries in your sitemap. | <literal>Sitemap</literal>是一个展示sitemap里一段项目的简单的Python类。 | 翻译 | ||
| 423#翻译 | For example, one <literal>Sitemap</literal> class could represent all the entries of your weblog, while another could represent all of the events in your events calendar. | 例如,一个<literal>Sitemap</literal>类可以展现你博客上的所有项目,另一个可以展现你日程表上的所有事件。 | 翻译 | ||
| 425#翻译 | In the simplest case, all these sections get lumped together into one <literal>sitemap.xml</literal> , but it's also possible to use the framework to generate a sitemap index that references individual sitemap files, one per section (as described shortly). | 在最简单的例子中,所有部分可以全部包含在一个 <literal>sitemap.xml</literal> 中,也可以使用框架来产生一个站点地图,为每一个独立的部分产生一个单独的站点文件。 | 翻译 | ||
| 427#翻译 | <literal>Sitemap</literal> classes must subclass <literal>django.contrib.sitemaps.Sitemap</literal> . They can live anywhere in your code tree. | <literal>Sitemap</literal> 类必须是 <literal>django.contrib.sitemaps.Sitemap</literal> 的子类. 他们可以存在于您的代码树的任何地方。 | 翻译 | ||
| 429#翻译 | For example, let's assume you have a blog system, with an <literal>Entry</literal> model, and you want your sitemap to include all the links to your individual blog entries. | 例如假设你有一个blog系统,有一个 <literal>Entry</literal> 的model,并且你希望你的站点地图包含所有连到你的blog入口的超链接。 | 翻译 | ||
| 430#翻译 | Here's how your <literal>Sitemap</literal> class might look: | 你的 <literal>Sitemap</literal> 类很可能是这样的: | 翻译 | ||
| 433#翻译 | Declaring a <literal>Sitemap</literal> should look very similar to declaring a <literal>Feed</literal> . That's by design. | 声明一个 <literal>Sitemap</literal> 和声明一个 <literal>Feed</literal> 看起来很类似;这都是预先设计好的。 | 翻译 | ||
| 435#翻译 | Like <literal>Feed</literal> classes, <literal>Sitemap</literal> members can be either methods or attributes. | 如同 <literal>Feed</literal> 类一样, <literal>Sitemap</literal> 成员既可以是方法,也可以是属性。 | 翻译 | ||
| 436#翻译 | See the steps in the earlier A Complex Example section for more about how this works. | 想要知道更详细的内容,请参见上文 《一个复杂的例子》章节。 | 翻译 | ||
| 438#翻译 | A <literal>Sitemap</literal> class can define the following methods/attributes: | 一个 <literal>Sitemap</literal> 类可以定义如下 方法/属性: | 翻译 | ||
| 440#翻译 | <literal>items</literal> (<strong>required</strong> ): Provides list of objects. | <literal>items</literal> (<strong>必需</strong> ):提供对象列表。 | 翻译 | ||
| 441#翻译 | The framework doesn't care what <emphasis>type</emphasis> of objects they are; all that matters is that these objects get passed to the <literal>location()</literal> , <literal>lastmod()</literal> , <literal>changefreq()</literal> , and <literal>priority()</literal> methods. | 框架并不关心对象的 <emphasis>类型</emphasis> ;唯一关心的是这些对象会传递给 <literal>location()</literal> , <literal>lastmod()</literal> , <literal>changefreq()</literal> ,和 <literal>priority()</literal> 方法。 | 翻译 | ||
| 443#翻译 | <literal>location</literal> (optional): | <literal>location</literal> (可选): | 翻译 | ||
| 444#翻译 | Gives the absolute URL for a given object. | 给定对象的绝对URL。 | 翻译 | ||
| 445#翻译 | Here, absolute URL means a URL that doesn't include the protocol or domain. | 绝对URL不包含协议名称和域名。 | 翻译 | ||
| 446#翻译 | Here are some examples: | 下面是一些例子: | 翻译 | ||
| 448#翻译 | Good: | 好的: | 翻译 | ||
| 449#翻译 | <literal>'/foo/bar/'</literal> | <literal>'/foo/bar/'</literal> | 翻译 | ||
| 451#翻译 | Bad: | 差的: | 翻译 | ||
| 452#翻译 | <literal>'example.com/foo/bar/'</literal> | <literal>'example.com/foo/bar/'</literal> | 翻译 | ||
| 454#翻译 | Bad: | 差的: | 翻译 | ||
| 455#翻译 | <literal>'http://example.com/foo/bar/'</literal> | 'http://example.com/foo/bar/' | 翻译 | ||
| 457#翻译 | If <literal>location</literal> isn't provided, the framework will call the <literal>get_absolute_url()</literal> method on each object as returned by <literal>items()</literal> . | 如果没有提供 <literal>location</literal> , 框架将会在每个 <literal>items()</literal> 返回的对象上调用 <literal>get_absolute_url()</literal> 方法. | 翻译 | ||
| 459#翻译 | <literal>lastmod</literal> (optional): | <literal>lastmod</literal> (可选): | 翻译 | ||
| 460#翻译 | The object's last modification date, as a Python <literal>datetime</literal> object. | 对象的最后修改日期, 作为一个Pythondatetime对象。 | 翻译 | ||
| 462#翻译 | <literal>changefreq</literal> (optional): | <literal>changefreq</literal> (可选): | 翻译 | ||
| 463#翻译 | How often the object changes. | 对象变更的频率。 | 翻译 | ||
| 464#翻译 | Possible values (as given by the Sitemaps specification) are as follows: | 可选的值如下(详见Sitemaps文档): | 翻译 | ||
| 466#翻译 | <literal>'always'</literal> | <literal>'always'</literal> | 翻译 | ||
| 468#翻译 | <literal>'hourly'</literal> | <literal>'hourly'</literal> | 翻译 | ||
| 470#翻译 | <literal>'daily'</literal> | <literal>'daily'</literal> | 翻译 | ||
| 472#翻译 | <literal>'weekly'</literal> | <literal>'weekly'</literal> | 翻译 | ||
| 474#翻译 | <literal>'monthly'</literal> | <literal>'monthly'</literal> | 翻译 | ||
| 476#翻译 | <literal>'yearly'</literal> | <literal>'yearly'</literal> | 翻译 | ||
| 478#翻译 | <literal>'never'</literal> | <literal>'never'</literal> | 翻译 | ||
| 480#翻译 | <literal>priority</literal> (optional): | <literal>priority</literal> (可选): | 翻译 | ||
| 481#翻译 | A suggested indexing priority between <literal>0.0</literal> and <literal>1.0</literal> . The default priority of a page is <literal>0.5</literal> ; see the <reference name="http://sitemaps.org/" refuri="http://sitemaps.org/">http://sitemaps.org/</reference> documentation for more about how <literal>priority</literal> works. | 取值范围在 <literal>0.0</literal> and <literal>1.0</literal> 之间,用来表明优先级。页面的默认优先级是<literal>0.5</literal>;参看文档<reference name="http://sitemaps.org/" refuri="http://sitemaps.org/">http://sitemaps.org/</reference>以了解更多。 | 翻译 | ||
| 483#翻译 | Shortcuts | 快捷方式 | 翻译 | ||
| 485#翻译 | The sitemap framework provides a couple convenience classes for common cases. | sitemap框架提供了一些常用的类。 | 翻译 | ||
| 486#翻译 | These are described in the sections that follow. | 在下一部分中会看到。 | 翻译 | ||
| 488#翻译 | FlatPageSitemap | FlatPageSitemap | 翻译 | ||
| 490#翻译 | The <literal>django.contrib.sitemaps.FlatPageSitemap</literal> class looks at all flat pages defined for the current site and creates an entry in the sitemap. | <literal>django.contrib.sitemaps.FlatPageSitemap</literal> 类涉及到站点中所有的flat page,并在sitemap中建立一个入口。 | 翻译 | ||
| 491#翻译 | These entries include only the <literal>location</literal> attribute not <literal>lastmod</literal> , <literal>changefreq</literal> , or <literal>priority</literal> . | 但仅仅只包含 <literal>location</literal> 属性,不支持 <literal>lastmod</literal> , <literal>changefreq</literal> ,或者 <literal>priority</literal> 。 | 翻译 | ||
| 493#翻译 | See Chapter 16 for more about flat pages. | 参见第16章获取有关flat page的更多的内容. | 翻译 | ||
| 495#翻译 | GenericSitemap | GenericSitemap | 翻译 | ||
| 497#翻译 | The <literal>GenericSitemap</literal> class works with any generic views (see Chapter 11) you already have. | <literal>GenericSitemap</literal> 与所有的通用视图一同工作(详见第11章)。 | 翻译 | ||
| 499#翻译 | To use it, create an instance, passing in the same <literal>info_dict</literal> you pass to the generic views. | 你可以如下使用它,创建一个实例,并通过 <literal>info_dict</literal> 传递给通用视图。 | 翻译 | ||
| 500#翻译 | The only requirement is that the dictionary have a <literal>queryset</literal> entry. | 唯一的要求是字典包含 <literal>queryset</literal> 这一项。 | 翻译 | ||
| 501#翻译 | It may also have a <literal>date_field</literal> entry that specifies a date field for objects retrieved from the <literal>queryset</literal> . This will be used for the <literal>lastmod</literal> attribute in the generated sitemap. | 也可以用 <literal>date_field</literal> 来指明从 <literal>queryset</literal> 中取回的对象的日期域。这会被用作站点地图中的 lastmod 属性。 | 翻译 | ||
| 502#翻译 | You may also pass <literal>priority</literal> and <literal>changefreq</literal> keyword arguments to the <literal>GenericSitemap</literal> constructor to specify these attributes for all URLs. | 你也可以把<literal>priority</literal>和<literal>changefreq</literal>关键字参数传给<literal>GenericSitemap</literal>的构造器以为所有URL指定这些属性。 | 翻译 | ||
| 504#翻译 | Here's an example of a URLconf using both <literal>FlatPageSitemap</literal> and <literal>GenericSiteMap</literal> (with the hypothetical <literal>Entry</literal> object from earlier): | 下面是一个使用 <literal>FlatPageSitemap</literal> and <literal>GenericSiteMap</literal> (包括前面所假定的 <literal>Entry</literal> 对象)的URLconf: | 翻译 | ||
| 507#翻译 | Creating a Sitemap Index | 创建一个Sitemap索引 | 翻译 | ||
| 509#翻译 | The sitemap framework also has the ability to create a sitemap index that references individual sitemap files, one per each section defined in your <literal>sitemaps</literal> dictionary. | sitemap框架同样可以根据 <literal>sitemaps</literal> 字典中定义的单独的sitemap文件来建立索引。 | 翻译 | ||
| 510#翻译 | The only differences in usage are as follows: | 用法区别如下: | 翻译 | ||
| 512#翻译 | You use two views in your URLconf: | 您在您的URLconf 中使用了两个视图: | 翻译 | ||
| 513#翻译 | <literal>django.contrib.sitemaps.views.index</literal> and <literal>django.contrib.sitemaps.views.sitemap</literal> . | <literal> django.contrib.sitemaps.views.index</literal> 和<literal> django.contrib.sitemaps.views.sitemap</literal> | 翻译 | ||
| 515#翻译 | The <literal>django.contrib.sitemaps.views.sitemap</literal> view should take a <literal>section</literal> keyword argument. | <literal>django.contrib.sitemaps.views.sitemap</literal> 视图需要带一个 <literal>section</literal> 关键字参数. | 翻译 | ||
| 517#翻译 | Here is what the relevant URLconf lines would look like for the previous example: | 这里是前面的例子的相关的 URLconf 行看起来的样子: | 翻译 | ||
| 520#翻译 | This will automatically generate a <literal>sitemap.xml</literal> file that references both <literal>sitemap-flatpages.xml</literal> and <literal>sitemap-blog.xml</literal> . The <literal>Sitemap</literal> classes and the <literal>sitemaps</literal> dictionary don't change at all. | 这将自动生成一个 <literal>sitemap.xml</literal> 文件, 它同时引用 <literal>sitemap-flatpages.xml</literal> 和 <literal>sitemap-blog.xml</literal>。<literal>Sitemap</literal> 类和 <literal>sitemaps</literal> 字典根本没有更改. | 翻译 | ||
| 522#翻译 | Pinging Google | 通知Google | 翻译 | ||
| 524#翻译 | You may want to ping Google when your sitemap changes, to let it know to reindex your site. | 当你的sitemap变化的时候,你会想通知Google,以便让它对你的站点进行重新索引。 | 翻译 | ||
| 525#翻译 | The framework provides a function to do just that: | 框架就提供了这样的一个函数: | 翻译 | ||
| 526#翻译 | <literal>django.contrib.sitemaps.ping_google()</literal> . | <literal>django.contrib.sitemaps.ping_google()</literal> 。 | 翻译 | ||
| 528#翻译 | <literal>ping_google()</literal> takes an optional argument, <literal>sitemap_url</literal> , which should be the absolute URL of your site's sitemap (e.g., <literal>'/sitemap.xml'</literal> ). If this argument isn't provided, <literal>ping_google()</literal> will attempt to figure out your sitemap by performing a reverse lookup on your URLconf. | <literal>ping_google()</literal> 有一个可选的参数 <literal>sitemap_url</literal> ,它应该是你的站点地图(也就是:<literal>'/sitemap.xml'</literal>)的URL绝对地址。如果这个参数空缺,<literal>ping_google()</literal>会尝试通过反向查询你的URLconf来生成一个。 | 翻译 | ||
| 530#翻译 | <literal>ping_google()</literal> raises the exception <literal>django.contrib.sitemaps.SitemapNotFound</literal> if it cannot determine your sitemap URL. | 如果不能够确定你的sitemap URL, <literal>ping_google()</literal> 会引发 <literal>django.contrib.sitemaps.SitemapNotFound</literal> 异常。 | 翻译 | ||
| 532#翻译 | One useful way to call <literal>ping_google()</literal> is from a model's <literal>save()</literal> method: | 我们可以通过模型中的 <literal>save()</literal> 方法来调用 <literal>ping_google()</literal> : | 翻译 | ||
| 535#翻译 | A more efficient solution, however, would be to call <literal>ping_google()</literal> from a <literal>cron</literal> script or some other scheduled task. | 一个更有效的解决方案是用 <literal>cron</literal> 脚本或任务调度表来调用 <literal>ping_google()</literal>。 | 翻译 | ||
| 536#翻译 | The function makes an HTTP request to Google's servers, so you may not want to introduce that network overhead each time you call <literal>save()</literal> . | 该方法使用Http直接请求Google服务器,从而减少每次调用save()时占用的网络带宽。 | 翻译 | ||
| 538#翻译 | Finally, if <literal>'django.contrib.sitemaps'</literal> is in your <literal>INSTALLED_APPS</literal> , then your <literal>manage.py</literal> will include a new command, <literal>ping_google</literal> . This is useful for command-line access to pinging. | 最后,如果<literal>'django.contrib.sitemaps'</literal>包含在你的<literal>INSTALLED_APPS</literal>下,那么你的<literal>manage.py</literal>将新增一个<literal>ping_google</literal>命令,这在命令行下很有用处。 | 翻译 | ||
| 539#翻译 | For example: | 例如: | 翻译 | ||
| 542#翻译 | What's Next? | 下一章 | 翻译 | ||
| 544#翻译 | Next, we'll continue to dig deeper into the built-in tools Django gives you. | 下面, 我们要继续深入Django提供给你的内置工具。 | 翻译 | ||
| 545#翻译 | <reference name="Chapter 14" refuri="../chapter14/">Chapter 14</reference> looks at all the tools you need to provide user-customized sites: | <reference name="Chapter 14" refuri="../chapter14/"> 第十四章</reference> 查看创建用户自定义站点需要的工具: | 翻译 | ||
| 546#翻译 | sessions, users, and authentication. | 会话(sessions),用户(users)和认证(authentication)。 | 翻译 |