| ID | English原文 | 中文翻译 | 最近翻译记录 | 状态 | 操作 |
|---|---|---|---|---|---|
| 0#翻译 | Chapter 16: | 第十六章:集成的子框架 | 翻译 | ||
| 1#翻译 | django.contrib | django.contrib | 翻译 | ||
| 4#翻译 | One of the many strengths of Python is its batteries included philosophy: | Python有众多优点,其中之一就是“开机即用”原则: | 翻译 | ||
| 5#翻译 | when you install Python, it comes with a large standard library of packages that you can start using immediately, without having to download anything else. | 安装Python的同时会安装好大量的标准软件包,这样 你可以立即使用而不用自己去下载。 | 翻译 | ||
| 6#翻译 | Django aims to follow this philosophy, and it includes its own standard library of add-ons useful for common Web development tasks. | Django也遵循这个原则,它同样包含了自己的标准库。 | 翻译 | ||
| 7#翻译 | This chapter covers that collection of add-ons. | 这一章就来讲 这些集成的子框架。 | 翻译 | ||
| 9#翻译 | The Django Standard Library | Django标准库 | 翻译 | ||
| 11#翻译 | Django's standard library lives in the package <literal>django.contrib</literal> . Within each subpackage is a separate piece of add-on functionality. | Django的标准库存放在 <literal>django.contrib</literal> 包中。每个子包都是一个独立的附加功能包。 | 翻译 | ||
| 12#翻译 | These pieces are not necessarily related, but some <literal>django.contrib</literal> subpackages may require other ones. | 这些子包一般是互相独立的,不过有些<literal>django.contrib</literal>子包需要依赖其他子包。 | 翻译 | ||
| 14#翻译 | There's no hard requirement for the types of functionality in <literal>django.contrib</literal> . Some of the packages include models (and hence require you to install their database tables into your database), but others consist solely of middleware or template tags. | 在 <literal>django.contrib</literal> 中对函数的类型并没有强制要求 。其中一些包中带有模型(因此需要你在数据库中安装对应的数据表),但其它一些由独立的中间件及模板标签组成。 | 翻译 | ||
| 16#翻译 | The single characteristic the <literal>django.contrib</literal> packages have in common is this: | <literal>django.contrib</literal> 开发包共有的特性是: | 翻译 | ||
| 17#翻译 | if you were to remove the <literal>django.contrib</literal> package entirely, you could still use Django's fundamental features with no problems. | 就算你将整个<literal>django.contrib</literal>开发包删除,你依然可以使用 Django 的基础功能而不会遇到任何问题。 | 翻译 | ||
| 18#翻译 | When the Django developers add new functionality to the framework, they use this rule of thumb in deciding whether the new functionality should live in <literal>django.contrib</literal> or elsewhere. | 当 Django 开发者向框架增加新功能的时,他们会严格根据这一原则来决定是否把新功能放入<literal>django.contrib</literal>中。 | 翻译 | ||
| 20#翻译 | <literal>django.contrib</literal> consists of these packages: | <literal>django.contrib</literal> 由以下开发包组成: | 翻译 | ||
| 22#翻译 | <literal>admin</literal> : The Django admin site. | <literal>admin</literal> : 自动化的站点管理工具。 | 翻译 | ||
| 23#翻译 | See Chapter 6. | 请查看第6章。 | 翻译 | ||
| 25#翻译 | <literal>admindocs</literal> : Auto-documentation for the Django admin site. | <literal>admindocs</literal>:为Django admin站点提供自动文档。 | 翻译 | ||
| 26#翻译 | This book doesn't cover this feature; check the official Django documentation. | 本书没有介绍这方面的知识;详情请参阅Django官方文档。 | 翻译 | ||
| 28#翻译 | <literal>auth</literal> : Django's authentication framework. | <literal>auth</literal> : Django的用户验证框架。 | 翻译 | ||
| 29#翻译 | See Chapter 14. | 参见第十四章。 | 翻译 | ||
| 31#翻译 | <literal>comments</literal> : A comments application. | <literal>comments</literal> : 一个评论应用,目前,这个应用正在紧张的开发中,因此在本书出版的时候还不能给出一个完整的说明,关于这个应用的更多信息请参见Django的官方网站. | 翻译 | ||
| 32#翻译 | This book doesn't cover this feature; check the official Django documentation. | 本书没有介绍这方面的知识;详情请参阅Django官方文档。 | 翻译 | ||
| 34#翻译 | <literal>contenttypes</literal> : A framework for hooking into types of content, where each installed Django model is a separate content type. | <literal>contenttypes</literal> : 这是一个用于引入文档类型的框架,每个安装的Django模块作为一种独立的文档类型。 | 翻译 | ||
| 35#翻译 | This framework is used internally by other contrib applications and is mostly intended for very advanced Django developers. | 这个框架主要在Django内部被其他应用使用,它主要面向Django的高级开发者。 | 翻译 | ||
| 36#翻译 | Those developers should find out more about this application by reading the source code in <literal>django/contrib/contenttypes</literal> . | 可以通过阅读源码来了解关于这个框架的更多信息,源码的位置在 <literal>django/contrib/contenttypes/</literal>。 | 翻译 | ||
| 38#翻译 | <literal>csrf</literal> : Protection against Cross-Site Request Forgery (CSRF). | <literal>csrf</literal> : 这个模块用来防御跨站请求伪造(CSRF)。参 | 翻译 | ||
| 39#翻译 | See the later section titled CSRF Protection. | 见后面标题为"CSRF 防御"的小节。 | 翻译 | ||
| 41#翻译 | <literal>databrowse</literal> : A Django application that lets you browse your data. | <literal>databrowse</literal>:帮助你浏览数据的Django应用。 | 翻译 | ||
| 42#翻译 | This book doesn't cover this feature; check the official Django documentation. | 本书没有介绍这方面的知识;详情请参阅Django官方文档。 | 翻译 | ||
| 44#翻译 | <literal>flatpages</literal> : A framework for managing simple flat HTML content in a database. | <literal>flatpages</literal> : 一个在数据库中管理单一HTML内容的模块。 | 翻译 | ||
| 45#翻译 | See the later section titled Flatpages. | 参见后面标题为“Flatpages”的小节。 | 翻译 | ||
| 47#翻译 | <literal>formtools</literal> : A number of useful higher-level libraries for dealing with common patterns in forms. | <literal>formtools</literal>:一些列处理表单通用模式的高级库。 | 翻译 | ||
| 48#翻译 | This book doesn't cover this feature; check the official Django documentation. | 本书没有介绍这方面的知识;详情请参阅Django官方文档。 | 翻译 | ||
| 50#翻译 | <literal>gis</literal> : Extensions to Django that provide for GIS (Geographic Information Systems) support. | <literal>gis</literal>:为Django提供GIS(Geographic Information Systems)支持的扩展。 | 翻译 | ||
| 51#翻译 | These, for example, allow your Django models to store geographic data and perform geographic queries. | 举个例子,它允许你的Django模型保存地理学数据并执行地理学查询。 | 翻译 | ||
| 52#翻译 | This is a large, complex library and isn't covered in this book. | 这个库比较复杂,本书不详细介绍。 | 翻译 | ||
| 53#翻译 | See <reference name="http://geodjango.org/" refuri="http://geodjango.org/">http://geodjango.org/</reference> for documentation. | 请参看<reference name="http://geodjango.org/" refuri="http://geodjango.org/">http://geodjango.org/</reference>上的文档。 | 翻译 | ||
| 55#翻译 | <literal>humanize</literal> : A set of Django template filters useful for adding a human touch to data. | <literal>humanize</literal> : 一系列 Django 模块过滤器,用于增加数据的人性化。 | 翻译 | ||
| 56#翻译 | See the later section titled Humanizing Data. | 参阅稍后的章节《人性化数据》。 | 翻译 | ||
| 58#翻译 | <literal>localflavor</literal> : Assorted pieces of code that are useful for particular countries or cultures. | <literal>localflavor</literal>:针对不同国家和文化的混杂代码段。 | 翻译 | ||
| 59#翻译 | For example, this includes ways to validate U.S. | 例如,它包含了验证美国的邮编 | 翻译 | ||
| 60#翻译 | ZIP codes or Icelandic identification numbers. | 以及爱尔兰的身份证号的方法。 | 翻译 | ||
| 62#翻译 | <literal>markup</literal> : A set of Django template filters that implement a number of common markup languages. | <literal>markup</literal> : 一系列的 Django 模板过滤器,用于实现一些常用标记语言。 | 翻译 | ||
| 63#翻译 | See the later section titled Markup Filters. | 参阅后续章节《标记过滤器》。 | 翻译 | ||
| 65#翻译 | <literal>redirects</literal> : A framework for managing redirects. | <literal>redirects</literal> : 用来管理重定向的框架。 | 翻译 | ||
| 66#翻译 | See the later section titled Redirects. | 参看后面的“重定向”小节。 | 翻译 | ||
| 68#翻译 | <literal>sessions</literal> : Django's session framework. | <literal>sessions</literal> : Django 的会话框架。 | 翻译 | ||
| 69#翻译 | See Chapter 14. | 参见14章。 | 翻译 | ||
| 71#翻译 | <literal>sitemaps</literal> : A framework for generating sitemap XML files. | <literal>sitemaps</literal> : 用来生成网站地图的 XML 文件的框架。 | 翻译 | ||
| 72#翻译 | See Chapter 13. | 参见13章。 | 翻译 | ||
| 74#翻译 | <literal>sites</literal> : A framework that lets you operate multiple Web sites from the same database and Django installation. | <literal>sites</literal> : 一个让你可以在同一个数据库与 Django 安装中管理多个网站的框架。 | 翻译 | ||
| 75#翻译 | See the next section, Sites. | 参见下一节: | 翻译 | ||
| 77#翻译 | <literal>syndication</literal> : A framework for generating syndication feeds in RSS and Atom. | <literal>syndication</literal> : 一个用 RSS 和 Atom 来生成聚合订阅源的的框架。 | 翻译 | ||
| 78#翻译 | See Chapter 13. | 参见13章。 | 翻译 | ||
| 80#翻译 | <literal>webdesign</literal> : Django add-ons that are particularly useful to Web <emphasis>designers</emphasis> (as opposed to developers). | <literal>webdesign</literal>:对设计者非常有用的Django扩展。 | 翻译 | ||
| 81#翻译 | As of this writing, this included only a single template tag, <literal>{% lorem %}</literal> . Check the Django documentation for information. | 到编写此文时,它只包含一个模板标签<literal>{% lorem %}</literal>。详情参阅Django文档。 | 翻译 | ||
| 83#翻译 | The rest of this chapter goes into detail a number of <literal>django.contrib</literal> packages that we haven't yet covered in this book. | 本章接下来将详细描述前面没有介绍过的 <literal>django.contrib</literal> 开发包内容。 | 翻译 | ||
| 85#翻译 | Sites | 多个站点 | 翻译 | ||
| 87#翻译 | Django's sites system is a generic framework that lets you operate multiple Web sites from the same database and Django project. | Django 的多站点系统是一种通用框架,它让你可以在同一个数据库和同一个Django项目下操作多个网站。 | 翻译 | ||
| 88#翻译 | This is an abstract concept, and it can be tricky to understand, so we'll start with a couple of scenarios where it would be useful. | 这是一个抽象概念,理解起来可能有点困难,因此我们从几个让它能派上用场的实际情景入手。 | 翻译 | ||
| 90#翻译 | Scenario 1: Reusing Data on Multiple Sites | 情景1:多站点间复用数据 | 翻译 | ||
| 92#翻译 | As we explained in Chapter 1, the Django-powered sites LJWorld.com and Lawrence.com are operated by the same news organization: | 正如我们在第一章里所讲,Django 构建的网站 LJWorld.com 和 Lawrance.com 是用由同一个新闻组织控制的: | 翻译 | ||
| 93#翻译 | the <emphasis>Lawrence Journal-World</emphasis> newspaper in Lawrence, Kansas. | 肯萨斯州劳伦斯市的 <emphasis>劳伦斯日报世界</emphasis> 报纸。 | 翻译 | ||
| 94#翻译 | LJWorld.com focuses on news, while Lawrence.com focuses on local entertainment. | LJWorld.com 主要做新闻,而 Lawrence.com 关注本地娱乐。 | 翻译 | ||
| 95#翻译 | But sometimes editors want to publish an article on <emphasis>both</emphasis> sites. | 然而有时,编辑可能需要把一篇文章发布到 <emphasis>两个</emphasis> 网站上。 | 翻译 | ||
| 97#翻译 | The brain-dead way of solving the problem would be to use a separate database for each site and to require site producers to publish the same story twice: | 解决此问题的死脑筋方法可能是使用每个站点分别使用不同的数据库,然后要求站点维护者把同一篇文章发布两次: | 翻译 | ||
| 98#翻译 | once for LJWorld.com and again for Lawrence.com. | 一次为 LJWorld.com,另一次为Lawrence.com。 | 翻译 | ||
| 99#翻译 | But that's inefficient for site producers, and it's redundant to store multiple copies of the same story in the database. | 但这对站点管理员来说是低效率的,而且为同一篇文章在数据库里保留多个副本也显得多余。 | 翻译 | ||
| 101#翻译 | The better solution? | 更好的解决方案? | 翻译 | ||
| 102#翻译 | Both sites use the same article database, and an article is associated with one or more sites via a many-to-many relationship. | 两个网站用的是同一个文章数据库,并将每一篇文章与一个或多个站点用多对多关系关联起来。 | 翻译 | ||
| 103#翻译 | The Django sites framework provides the database table to which articles can be related. | Django 站点框架提供数据库表来记载哪些文章可以被关联。 | 翻译 | ||
| 104#翻译 | It's a hook for associating data with one or more sites. | 它是一个把数据与一个或多个站点关联起来的钩子。 | 翻译 | ||
| 106#翻译 | Scenario 2: Storing Your Site Name/Domain in One Place | 情景2:把网站的名字/域名保存在一个地方 | 翻译 | ||
| 108#翻译 | LJWorld.com and Lawrence.com both have e-mail alert functionality, which lets readers sign up to get notifications when news happens. | LJWorld.com 和 Lawrence.com 都有邮件提醒功能,使读者注册后可以在新闻发生后立即收到通知。 | 翻译 | ||
| 109#翻译 | It's pretty basic: | 这是一种完美的的机制: | 翻译 | ||
| 110#翻译 | a reader signs up on a Web form, and he immediately gets an e-mail saying, Thanks for your subscription. | 某读者提交了注册表单,然后马上就受到一封内容是“感谢您的注册”的邮件。 | 翻译 | ||
| 112#翻译 | It would be inefficient and redundant to implement this signup-processing code twice, so the sites use the same code behind the scenes. | 把这个注册过程的代码实现两遍显然是低效、多余的,因此两个站点在后台使用相同的代码。 | 翻译 | ||
| 113#翻译 | But the Thank you for your subscription notice needs to be different for each site. | 但感谢注册的通知在两个网站中需要不同。 | 翻译 | ||
| 114#翻译 | By using <literal>Site</literal> objects, we can abstract the thank-you notice to use the values of the current site's <literal>name</literal> (e.g., <literal>'LJWorld.com'</literal> ) and <literal>domain</literal> (e.g., <literal>'www.ljworld.com'</literal> ). | 通过使用 <literal>Site</literal> 对象,我们通过使用当前站点的 <literal>name</literal> (例如 <literal>'LJWorld.com'</literal> )和 <literal>domain</literal> (例如 <literal>'www.ljworld.com'</literal> )可以把感谢通知抽提出来。 | 翻译 | ||
| 116#翻译 | The Django sites framework provides a place for you to store the <literal>name</literal> and <literal>domain</literal> for each site in your Django project, which means you can reuse those values in a generic way. | Django 的多站点框架为你提供了一个位置来存储 Django 项目中每个站点的 <literal>name</literal> 和 <literal>domain</literal> ,这意味着你可以用同样的方法来重用这些值。 | 翻译 | ||
| 118#翻译 | How to Use the Sites Framework | 如何使用多站点框架 | 翻译 | ||
| 120#翻译 | The sites framework is more a series of conventions than a framework. | 多站点框架与其说是一个框架,不如说是一系列约定。 | 翻译 | ||
| 121#翻译 | The whole thing is based on two simple concepts: | 所有的一切都基于两个简单的概念: | 翻译 | ||
| 123#翻译 | The <literal>Site</literal> model, found in <literal>django.contrib.sites</literal> , has <literal>domain</literal> and <literal>name</literal> fields. | 位于 <literal>django.contrib.sites</literal> 的 <literal>Site</literal> 模型有 <literal>domain</literal> 和 <literal>name</literal> 两个字段。 | 翻译 | ||
| 125#翻译 | The <literal>SITE_ID</literal> setting specifies the database ID of the <literal>Site</literal> object associated with that particular settings file. | <literal>SITE_ID</literal> 设置指定了与特定配置文件相关联的 <literal>Site</literal> 对象之数据库 ID。 | 翻译 | ||
| 127#翻译 | How you use these two concepts is up to you, but Django uses them in a couple of ways automatically via simple conventions. | 如何运用这两个概念由你决定,但 Django 是通过几个简单的约定自动使用的。 | 翻译 | ||
| 129#翻译 | To install the sites application, follow these steps: | 安装多站点应用要执行以下几个步骤: | 翻译 | ||
| 131#翻译 | Add <literal>'django.contrib.sites'</literal> to your <literal>INSTALLED_APPS</literal> . | 将 <literal>'django.contrib.sites'</literal> 加入到 <literal>INSTALLED_APPS</literal> 中。 | 翻译 | ||
| 133#翻译 | Run the command <literal>manage.py syncdb</literal> to install the <literal>django_site</literal> table into your database. | 运行 <title_reference>manage.py syncdb</title_reference> 命令将 <title_reference>django_site</title_reference> 表安装到数据库中。 | 翻译 | ||
| 134#翻译 | This will also create a default site object, with the domain <literal>example.com</literal> . | 这样也会建立默认的站点对象,域名为 example.com。 | 翻译 | ||
| 136#翻译 | Change the <literal>example.com</literal> site to your own domain, and add any other <literal>Site</literal> objects, either through the Django admin site or via the Python API. | 把<literal>example.com</literal>改成你自己的域名,然后通过Django admin站点或Python API来添加其他<literal>Site</literal>对象。 | 翻译 | ||
| 137#翻译 | Create a <literal>Site</literal> object for each site/domain that this Django project powers. | 为该 Django 项目支撑的每个站(或域)创建一个 <literal>Site</literal> 对象。 | 翻译 | ||
| 139#翻译 | Define the <literal>SITE_ID</literal> setting in each of your settings files. | 在每个设置文件中定义一个 <literal>SITE_ID</literal> 变量。 | 翻译 | ||
| 140#翻译 | This value should be the database ID of the <literal>Site</literal> object for the site powered by that settings file. | 该变量值应当是该设置文件所支撑的站点<literal>Site</literal> 对象的数据库 ID。 | 翻译 | ||
| 142#翻译 | The Sites Framework's Capabilities | 多站点框架的功能 | 翻译 | ||
| 144#翻译 | The sections that follow describe the various things you can do with the sites framework. | 下面几节讲述的是用多站点框架能够完成的几项工作。 | 翻译 | ||
| 146#翻译 | Reusing Data on Multiple Sites | 多个站点的数据重用 | 翻译 | ||
| 148#翻译 | To reuse data on multiple sites, as explained in the first scenario, just create a <literal>ManyToManyField</literal> to <literal>Site</literal> in your models, for example: | 正如在情景一中所解释的,要在多个站点间重用数据,仅需在模型中为 <literal>Site</literal> 添加一个 <literal>多对多字段</literal> 即可,例如: | 翻译 | ||
| 151#翻译 | That's the infrastructure you need to associate articles with multiple sites in your database. | 这是在数据库中为多个站点进行文章关联操作的基础步骤。 | 翻译 | ||
| 152#翻译 | With that in place, you can reuse the same Django view code for multiple sites. | 在适当的位置使用该技术,你可以在多个站点中重复使用同一段 Django 视图代码。 | 翻译 | ||
| 153#翻译 | Continuing the <literal>Article</literal> model example, here's what an <literal>article_detail</literal> view might look like: | 继续 <literal>Article</literal> 模型范例,下面是一个可能的 <literal>article_detail</literal> 视图: | 翻译 | ||
| 156#翻译 | This view function is reusable because it checks the article's site dynamically, according to the value of the <literal>SITE_ID</literal> setting. | 该视图方法是可重用的,因为它根据 <literal>SITE_ID</literal> 设置的值动态检查 articles 站点。 | 翻译 | ||
| 158#翻译 | For example, say LJWorld.com's settings file has a <literal>SITE_ID</literal> set to <literal>1</literal> , and Lawrence.com's settings file has a <literal>SITE_ID</literal> set to <literal>2</literal> . If this view is called when LJWorld.com's settings file is active, then it will limit the article lookup to articles in which the list of sites includes LJWorld.com. | 例如, LJWorld.coms 设置文件中有有个 <literal>SITE_ID</literal> 设置为 <literal>1</literal> ,而 Lawrence.coms 设置文件中有个 <literal>SITE_ID</literal> 设置为 <literal>2</literal> 。如果该视图在 LJWorld.coms 处于激活状态时被调用,那么它将把查找范围局限于站点列表包括 LJWorld.com 在内的文章。 | 翻译 | ||
| 160#翻译 | Associating Content with a Single Site | 将内容与单一站点相关联 | 翻译 | ||
| 162#翻译 | Similarly, you can associate a model to the <literal>Site</literal> model in a many-to-one relationship using <literal>ForeignKey</literal> . | 同样,你也可以使用 <literal>外键</literal> 在多对一关系中将一个模型关联到 <literal>Site</literal> 模型。 | 翻译 | ||
| 164#翻译 | For example, if each article is associated with only a single site, you could use a model like this: | 举例来说,如果某篇文章仅仅能够出现在一个站点上,你可以使用下面这样的模型: | 翻译 | ||
| 167#翻译 | This has the same benefits as described in the last section. | 这与前一节中介绍的一样有益。 | 翻译 | ||
| 169#翻译 | Hooking Into the Current Site from Views | 从视图钩挂当前站点 | 翻译 | ||
| 171#翻译 | On a lower level, you can use the sites framework in your Django views to do particular things based on the site in which the view is being called, for example: | 在底层,通过在 Django 视图中使用多站点框架,你可以让视图根据调用站点不同而完成不同的工作,例如: | 翻译 | ||
| 174#翻译 | Of course, it's ugly to hard-code the site IDs like that. | 当然,像那样对站点 ID 进行硬编码是比较难看的。 | 翻译 | ||
| 175#翻译 | A slightly cleaner way of accomplishing the same thing is to check the current site's domain: | 略为简洁的完成方式是查看当前的站点域: | 翻译 | ||
| 178#翻译 | The idiom of retrieving the <literal>Site</literal> object for the value of <literal>settings.SITE_ID</literal> is quite common, so the <literal>Site</literal> model's manager (<literal>Site.objects</literal> ) has a <literal>get_current()</literal> method. | 从 <literal>Site</literal> 对象中获取 <literal>settings.SITE_ID</literal> 值的做法比较常见,因此 <literal>Site</literal> 模型管理器 (<literal>Site.objects</literal> ) 具备一个 <literal>get_current()</literal> 方法。 | 翻译 | ||
| 179#翻译 | This example is equivalent to the previous one: | 下面的例子与前一个是等效的: | 翻译 | ||
| 182#翻译 | Note | 注意 | 翻译 | ||
| 184#翻译 | In this final example, you don't have to import <literal>django.conf.settings</literal> . | 在这个最后的例子里,你不用导入 <literal>django.conf.settings</literal> 。 | 翻译 | ||
| 186#翻译 | Getting the Current Domain for Display | 获取当前域用于呈现 | 翻译 | ||
| 188#翻译 | For a DRY (Don't Repeat Yourself) approach to storing your site's name and domain name, as explained in Scenario 2: Storing Your Site Name/Domain in One Place, just reference the <literal>name</literal> and <literal>domain</literal> of the current <literal>Site</literal> object. | 正如情景二中所解释的那样,依据DRY原则(不做重复工作),你只需在一个位置储存站名和域名,然后引用当前 <literal>Site</literal> 对象的 <literal>name</literal> 和 <literal>domain</literal> 。例如: | 翻译 | ||
| 189#翻译 | For example: | 例如: | 翻译 | ||
| 192#翻译 | Continuing our ongoing example of LJWorld.com and Lawrence.com, on Lawrence.com this e-mail has the subject line Thanks for subscribing to lawrence.com alerts. | 继续我们正在讨论的 LJWorld.com 和 Lawrence.com 例子,在Lawrence.com 该邮件的标题行是“感谢注册 Lawrence.com 提醒信件”。 | 翻译 | ||
| 193#翻译 | On LJWorld.com, the e-mail has the subject line Thanks for subscribing to LJWorld.com alerts. | 在 LJWorld.com ,该邮件标题行是“感谢注册 LJWorld.com 提醒信件”。 | 翻译 | ||
| 194#翻译 | This same site-specific behavior is applied to the e-mails' message body. | 这种站点关联行为方式对邮件信息主体也同样适用。 | 翻译 | ||
| 196#翻译 | An even more flexible (but more heavyweight) way of doing this would be to use Django's template system. | 完成这项工作的一种更加灵活(但更重量级)的方法是使用 Django 的模板系统。 | 翻译 | ||
| 197#翻译 | Assuming Lawrence.com and LJWorld.com have different template directories (<literal>TEMPLATE_DIRS</literal> ), you could simply delegate to the template system like so: | 假定 Lawrence.com 和 LJWorld.com 各自拥有不同的模板目录( <literal>TEMPLATE_DIRS</literal> ),你可将工作轻松地转交给模板系统,如下所示: | 翻译 | ||
| 200#翻译 | In this case, you have to create <literal>subject.txt</literal> and <literal>message.txt</literal> templates in both the LJWorld.com and Lawrence.com template directories. | 本例中,你不得不在 LJWorld.com 和 Lawrence.com 的模板目录中都创建一份 <literal>subject.txt</literal> 和 <literal>message.txt</literal> 模板。 | 翻译 | ||
| 201#翻译 | As mentioned previously, that gives you more flexibility, but it's also more complex. | 正如之前所说,该方法带来了更大的灵活性,但也带来了更多复杂性。 | 翻译 | ||
| 203#翻译 | It's a good idea to exploit the <literal>Site</literal> objects as much as possible to remove unneeded complexity and redundancy. | 尽可能多的利用 <literal>Site</literal> 对象是减少不必要的复杂、冗余工作的好办法。 | 翻译 | ||
| 205#翻译 | CurrentSiteManager | 当前站点管理器 | 翻译 | ||
| 207#翻译 | If <literal>Site</literal> objects play a key role in your application, consider using the <literal>CurrentSiteManager</literal> in your model(s). | 如果 <literal>站点</literal> 在你的应用中扮演很重要的角色,请考虑在你的模型中使用方便的 <literal>CurrentSiteManager</literal> 。 | 翻译 | ||
| 208#翻译 | It's a model manager (see Chapter 10) that automatically filters its queries to include only objects associated with the current <literal>Site</literal> . | 这是一个模型管理器(见第十章),它会自动过滤使其只包含与当前站点相关联的对象。 | 翻译 | ||
| 210#翻译 | Use <literal>CurrentSiteManager</literal> by adding it to your model explicitly. | 通过显示地将 <literal>CurrentSiteManager</literal> 加入模型中以使用它。 | 翻译 | ||
| 211#翻译 | For example: | 例如: | 翻译 | ||
| 214#翻译 | With this model, <literal>Photo.objects.all()</literal> will return all <literal>Photo</literal> objects in the database, but <literal>Photo.on_site.all()</literal> will return only the <literal>Photo</literal> objects associated with the current site, according to the <literal>SITE_ID</literal> setting. | 通过该模型, <literal>Photo.objects.all()</literal> 将返回数据库中所有的 <literal>Photo</literal> 对象,而 <literal>Photo.on_site.all()</literal> 仅根据 <literal>SITE_ID</literal> 设置返回与当前站点相关联的 <literal>Photo</literal> 对象。 | 翻译 | ||
| 216#翻译 | In other words, these two statements are equivalent: | 换言之,以下两条语句是等效的: | 翻译 | ||
| 219#翻译 | How did <literal>CurrentSiteManager</literal> know which field of <literal>Photo</literal> was the <literal>Site</literal> ? It defaults to looking for a field called <literal>site</literal> . If your model has a <literal>ForeignKey</literal> or <literal>ManyToManyField</literal> called something <emphasis>other</emphasis> than <literal>site</literal> , you need to explicitly pass that as the parameter to <literal>CurrentSiteManager</literal> . The following model, which has a field called <literal>publish_on</literal> , demonstrates this: | <literal>CurrentSiteManager</literal> 是如何知道 <literal>Photo</literal> 的哪个字段是 <literal>Site</literal> 呢?缺省情况下,它会查找一个叫做 <literal>site</literal> 的字段。如果你的模型包含了名字<literal>不是</literal><literal>site</literal>的<emphasis>外键</emphasis>或者<literal>多对多</literal>关联,你需要把它作为参数传给<literal>CurrentSiteManager</literal>以显示指明。下面的模型拥有一个<literal>publish_on</literal>字段: | 翻译 | ||
| 222#翻译 | If you attempt to use <literal>CurrentSiteManager</literal> and pass a field name that doesn't exist, Django will raise a <literal>ValueError</literal> . | 如果试图使用 <literal>CurrentSiteManager</literal> 并传入一个不存在的字段名, Django 将引发一个 <literal>ValueError</literal> 异常。 | 翻译 | ||
| 224#翻译 | Note | 注意 | 翻译 | ||
| 226#翻译 | You'll probably want to keep a normal (non-site-specific) <literal>Manager</literal> on your model, even if you use <literal>CurrentSiteManager</literal> . As explained in Appendix B, if you define a manager manually, then Django won't create the automatic <literal>objects = models.Manager()</literal> manager for you. | 即便是已经使用了 <literal>CurrentSiteManager</literal> ,你也许还想在模型中拥有一个正常的(非站点相关)的 <literal>管理器</literal> 。正如在附录 B 中所解释的,如果你手动定义了一个管理器,那么 Django 不会为你创建全自动的 <literal>objects = models.Manager()</literal> 管理器。 | 翻译 | ||
| 228#翻译 | Also, certain parts of Django namely, the Django admin site and generic views use whichever manager is defined <emphasis>first</emphasis> in the model, so if you want your admin site to have access to all objects (not just site-specific ones), put <literal>objects = models.Manager()</literal> in your model, before you define <literal>CurrentSiteManager</literal> . | 同样,Django 的特定部分(即 Django 超级管理站点和通用视图)使用在模型中定义 的<emphasis>第一个</emphasis>管理器,因此如果希望管理站点能够访问所有对象(而不是仅仅站点特有对象),请于定义 <literal>CurrentSiteManager</literal> 之前在模型中放入 <literal>objects = models.Manager()</literal> 。 | 翻译 | ||
| 230#翻译 | How Django Uses the Sites Framework | Django如何使用多站点框架 | 翻译 | ||
| 232#翻译 | Although it's not required that you use the sites framework, it's encouraged, because Django takes advantage of it in a few places. | 尽管并不是必须的,我们还是强烈建议使用多站点框架,因为 Django 在几个地方利用了它。 | 翻译 | ||
| 233#翻译 | Even if your Django installation is powering only a single site, you should take a few seconds to create the site object with your <literal>domain</literal> and <literal>name</literal> , and point to its ID in your <literal>SITE_ID</literal> setting. | 即使只用 Django 来支持单个网站,你也应该花一点时间用 <literal>domain</literal> 和 <literal>name</literal> 来创建站点对象,并将 <literal>SITE_ID</literal> 设置指向它的 ID 。 | 翻译 | ||
| 235#翻译 | Here's how Django uses the sites framework: | 以下讲述的是 Django 如何使用多站点框架: | 翻译 | ||
| 237#翻译 | In the redirects framework (see the later section Redirects), each redirect object is associated with a particular site. | 在重定向框架中(见后面的重定向一节),每一个重定向对象都与一个特定站点关联。 | 翻译 | ||
| 238#翻译 | When Django searches for a redirect, it takes into account the current <literal>SITE_ID</literal> . | 当 Django 搜索重定向的时候,它会考虑当前的 <literal>SITE_ID</literal> 。 | 翻译 | ||
| 240#翻译 | In the comments framework, each comment is associated with a particular site. | 在注册框架中,每个注释都与特定站点相关。 | 翻译 | ||
| 241#翻译 | When a comment is posted, its <literal>site</literal> is set to the current <literal>SITE_ID</literal> , and when comments are listed via the appropriate template tag, only the comments for the current site are displayed. | 每个注释被显示时,其 <literal>site</literal> 被设置为当前的 <literal>SITE_ID</literal> ,而当通过适当的模板标签列出注释时,只有当前站点的注释将会显示。 | 翻译 | ||
| 243#翻译 | In the flatpages framework (see the later section Flatpages), each flatpage is associated with a particular site. | 在 flatpages 框架中 (参见后面的 Flatpages 一节),每个 flatpage 都与特定的站点相关联。 | 翻译 | ||
| 244#翻译 | When a flatpage is created, you specify its <literal>site</literal> , and the flatpage middleware checks the current <literal>SITE_ID</literal> in retrieving flatpages to display. | 创建 flatpage 时,你都将指定它的 <literal>site</literal> ,而 flatpage 中间件在获取 flatpage 以显示它的过程中,将查看当前的 <literal>SITE_ID</literal> 。 | 翻译 | ||
| 246#翻译 | In the syndication framework (see Chapter 13), the templates for <literal>title</literal> and <literal>description</literal> automatically have access to a variable <literal>{{ site }}</literal> , which is the <literal>Site</literal> object representing the current site. | 在 syndication 框架中(参阅第 13 章), <literal>title</literal> 和 <literal>description</literal> 的模板会自动访问变量 <literal>{{ site }}</literal> ,它其实是代表当前站点的 <literal>Site</literal> 对象。 | 翻译 | ||
| 247#翻译 | Also, the hook for providing item URLs will use the <literal>domain</literal> from the current <literal>Site</literal> object if you don't specify a fully qualified domain. | 而且,如果你不指定一个合格的domain的话,提供目录URL的钩子将会使用当前“Site”对象的domain。 | 翻译 | ||
| 249#翻译 | In the authentication framework (see Chapter 14), the <literal>django.contrib.auth.views.login</literal> view passes the current <literal>Site</literal> name to the template as <literal>{{ site_name }}</literal> and the current <literal>Site</literal> object as <literal>{{ site }}</literal> . | 在权限框架中(参见十四章),视图<literal>django.contrib.auth.views.login</literal>把当前<literal>Site</literal>名字和对象分别以<literal>{{ site_name }}</literal>和<literal>{{ site }}</literal>的形式传给了模板。 | 翻译 | ||
| 251#翻译 | Flatpages | Flatpages(简单页面) | 翻译 | ||
| 253#翻译 | Often you'll have a database-driven Web application up and running, but you'll need to add a couple of one-off static pages, such as an About page or a Privacy Policy page. | 尽管通常情况下总是搭建运行数据库驱动的 Web 应用,有时你还是需要添加一两张一次性的静态页面,例如“关于”页面,或者“隐私策略”页面等等。 | 翻译 | ||
| 254#翻译 | It would be possible to use a standard Web server such as Apache to serve these files as flat HTML files, but that introduces an extra level of complexity into your application, because then you have to worry about configuring Apache, you have to set up access for your team to edit those files, and you can't take advantage of Djangos template system to style the pages. | 可以用像 Apache 这样的标准Web服务器来处理这些静态页面,但却会给应用带来一些额外的复杂性,因为你必须操心怎么配置 Apache,还要设置权限让整个团队可以修改编辑这些文件,而且你还不能使用 Django 模板系统来统一这些页面的风格。 | 翻译 | ||
| 256#翻译 | The solution to this problem is Django's flatpages application, which lives in the package <literal>django.contrib.flatpages</literal> . This application lets you manage such one-off pages via Django's admin site, and it lets you specify templates for them using Django's template system. | 这个问题的解决方案是使用位于 <literal>django.contrib.flatpages</literal> 开发包中的 Django 简单页面(flatpages)应用程序。该应用让你能够通过 Django 管理站点来管理这些一次性的页面,还可以让你使用 Django 模板系统指定它们使用哪个模板。 | 翻译 | ||
| 257#翻译 | It uses Django models behind the scenes, which means it stores the pages in a database, just like the rest of your data, and you can access flatpages with the standard Django database API. | 它在后台使用Django模型,这意味着它把页面项别的数据一样保存在数据库中,也就是说你可以使用标准Django数据库API来存取页面。 | 翻译 | ||
| 259#翻译 | Flatpages are keyed by their URL and site. | 简单页面以它们的 URL 和站点为键值。 | 翻译 | ||
| 260#翻译 | When you create a flatpage, you specify which URL it's associated with, along with which site(s) it's on. | 当创建简单页面时,你指定它与哪个URL以及和哪个站点相关联 。 | 翻译 | ||
| 261#翻译 | (For more on sites, see the Sites section.) | (有关站点的更多信息,请查阅”多站点“一节。) | 翻译 | ||
| 263#翻译 | Using Flatpages | 使用简单页面 | 翻译 | ||
| 265#翻译 | To install the flatpages application, follow these steps: | 安装简单页面应用程序必须按照下面的步骤: | 翻译 | ||
| 267#翻译 | Add <literal>'django.contrib.flatpages'</literal> to your <literal>INSTALLED_APPS</literal> . <literal>django.contrib.flatpages</literal> depends on <literal>django.contrib.sites</literal> , so make sure the both packages are in <literal>INSTALLED_APPS</literal> . | 添加 <literal>'django.contrib.flatpages'</literal> 到 <literal>INSTALLED_APPS</literal> 设置。<literal>django.contrib.flatpages</literal>依赖<literal>django.contrib.sites</literal>,所以确保它们都在<literal>INSTALLED_APPS</literal>里。 | 翻译 | ||
| 269#翻译 | Add <literal>'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'</literal> to your <literal>MIDDLEWARE_CLASSES</literal> setting. | 将 <literal>'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'</literal> 添加到 <literal>MIDDLEWARE_CLASSES</literal> 设置中。 | 翻译 | ||
| 271#翻译 | Run the command <literal>manage.py syncdb</literal> to install the two required tables into your database. | 运行 <literal>manage.py syncdb</literal> 命令在数据库中创建必需的两个表。 | 翻译 | ||
| 273#翻译 | The flatpages application creates two tables in your database: | 简单页面应用程序在数据库中创建两个表: | 翻译 | ||
| 274#翻译 | <literal>django_flatpage</literal> and <literal>django_flatpage_sites</literal> . <literal>django_flatpage</literal> simply maps a URL to a title and bunch of text content. | <literal>django_flatpage</literal> 和 <literal>django_flatpage_sites</literal> 。 <literal>django_flatpage</literal> 只是将 URL 映射到标题和一段文本内容。 | 翻译 | ||
| 275#翻译 | <literal>django_flatpage_sites</literal> is a many-to-many table that associates a flatpage with one or more sites. | <literal>django_flatpage_sites</literal> 是一个多对多表,用于关联某个简单页面以及一个或多个站点。 | 翻译 | ||
| 277#翻译 | The application comes with a single <literal>FlatPage</literal> model, defined in <literal>django/contrib/flatpages/models.py</literal> . It looks something like this: | 该应用捆绑的 <literal>FlatPage</literal> 模型在 <literal>django/contrib/flatpages/models.py</literal> 进行定义,如下所示: | 翻译 | ||
| 280#翻译 | Let's examine these fields one at a time: | 让我们逐项看看这些字段的含义: | 翻译 | ||
| 282#翻译 | <literal>url</literal> : The URL at which this flatpage lives, excluding the domain name but including the leading slash (e.g., <literal>/about/contact/</literal> ). | <literal>url</literal> : 该简单页面所处的 URL,不包括域名,但是包含前导斜杠 (例如 <literal>/about/contact/</literal> )。 | 翻译 | ||
| 284#翻译 | <literal>title</literal> : The title of the flatpage. | <literal>title</literal> : 简单页面的标题。 | 翻译 | ||
| 285#翻译 | The framework doesn't do anything special with this. | 框架不对它作任何特殊处理。 | 翻译 | ||
| 286#翻译 | Its your responsibility to display it in your template. | 由你通过模板来显示它。 | 翻译 | ||
| 288#翻译 | <literal>content</literal> : The content of the flatpage (i.e., the HTML of the page). | <literal>content</literal> : 简单页面的内容 (即 HTML 页面)。 | 翻译 | ||
| 289#翻译 | The framework doesn't do anything special with this. | 框架不对它作任何特殊处理。 | 翻译 | ||
| 290#翻译 | It's your responsibility to display it in the template. | 由你负责使用模板来显示。 | 翻译 | ||
| 292#翻译 | <literal>enable_comments</literal> : Whether to enable comments on this flatpage. | <literal>enable_comments</literal> : 是否允许该简单页面使用评论。 | 翻译 | ||
| 293#翻译 | The framework doesn't do anything special with this. | 框架不对它作任何特殊处理。 | 翻译 | ||
| 294#翻译 | You can check this value in your template and display a comment form if needed. | 你可在模板中检查该值并根据需要显示评论窗体。 | 翻译 | ||
| 296#翻译 | <literal>template_name</literal> : The name of the template to use for rendering this flatpage. | <literal>template_name</literal> : 用来解析该简单页面的模板名称。 | 翻译 | ||
| 297#翻译 | This is optional; if it's not given or if this template doesn't exist, the framework will fall back to the template <literal>flatpages/default.html</literal> . | 这是一个可选项;如果未指定模板或该模板不存在,系统会退而使用默认模板 <literal>flatpages/default.html</literal> 。 | 翻译 | ||
| 299#翻译 | <literal>registration_required</literal> : Whether registration is required for viewing this flatpage. | <literal>registration_required</literal> : 是否注册用户才能查看此简单页面。 | 翻译 | ||
| 300#翻译 | This integrates with Django's authentication/user framework, which is explained further in Chapter 14. | 该设置项集成了 Djangos 验证/用户框架,该框架于第十四章详述。 | 翻译 | ||
| 302#翻译 | <literal>sites</literal> : The sites that this flatpage lives on. | <literal>sites</literal> : 该简单页面放置的站点。 | 翻译 | ||
| 303#翻译 | This integrates with Django's sites framework, which is explained in the Sites section of this chapter. | 该项设置集成了 Django 多站点框架,该框架在本章的“多站点”一节中有所阐述。 | 翻译 | ||
| 305#翻译 | You can create flatpages through either the Django admin interface or the Django database API. | 你可以通过 Django 超级管理界面或者 Django 数据库 API 来创建简单页面。 | 翻译 | ||
| 306#翻译 | For more information on this, see the section Adding, Changing, and Deleting Flatpages. | 要了解更多内容,请查阅“添加、修改和删除简单页面”一节。 | 翻译 | ||
| 308#翻译 | Once you've created flatpages, <literal>FlatpageFallbackMiddleware</literal> does all of the work. | 一旦简单页面创建完成, <literal>FlatpageFallbackMiddleware</literal> 将完成(剩下)所有的工作。 | 翻译 | ||
| 309#翻译 | Each time any Django application raises a 404 error, this middleware checks the flatpages database for the requested URL as a last resort. | 每当 Django 引发 404 错误,作为最后的办法,该中间件将根据所请求的 URL 检查简单页面数据库。 | 翻译 | ||
| 310#翻译 | Specifically, it checks for a flatpage with the given URL with a site ID that corresponds to the <literal>SITE_ID</literal> setting. | 确切地说,它将使用所指定的 URL以及 <literal>SITE_ID</literal> 设置对应的站点 ID 查找一个简单页面。 | 翻译 | ||
| 312#翻译 | If it finds a match, it loads the flatpage's template or <literal>flatpages/default.html</literal> if the flatpage has not specified a custom template. | 如果找到一个匹配项,它将载入该简单页面的模板(如果没有指定的话,将使用默认模板 <literal>flatpages/default.html</literal> )。 | 翻译 | ||
| 313#翻译 | It passes that template a single context variable, <literal>flatpage</literal> , which is the <literal>FlatPage</literal> object. | 同时,它把一个简单的上下文变量<literal>flatpage</literal>(一个简单页面对象)传递给模板。 | 翻译 | ||
| 314#翻译 | It uses <literal>RequestContext</literal> in rendering the template. | 模板解析过程中,它实际用的是<literal>RequestContext</literal>。 | 翻译 | ||
| 316#翻译 | If <literal>FlatpageFallbackMiddleware</literal> doesn't find a match, the request continues to be processed as usual. | 如果 <literal>FlatpageFallbackMiddleware</literal> 没有找到匹配项,该请求继续如常处理。 | 翻译 | ||
| 318#翻译 | Note | 注意 | 翻译 | ||
| 320#翻译 | This middleware only gets activated for 404 (page not found) errors not for 500 (server error) or other error responses. | 该中间件仅在发生 404 (页面未找到)错误时被激活,而不会在 500 (服务器错误)或其他错误响应时被激活。 | 翻译 | ||
| 321#翻译 | Also note that the order of <literal>MIDDLEWARE_CLASSES</literal> matters. | 还要注意的是必须考虑 <literal>MIDDLEWARE_CLASSES</literal> 的顺序问题。 | 翻译 | ||
| 322#翻译 | Generally, you can put <literal>FlatpageFallbackMiddleware</literal> at or near the end of the list, because it's a last resort. | 通常,你可以把 <literal>FlatpageFallbackMiddleware</literal> 放在列表最后,因为它是最后的办法。 | 翻译 | ||
| 324#翻译 | Adding, Changing, and Deleting Flatpages | 添加、修改和删除简单页面 | 翻译 | ||
| 326#翻译 | You can add, change and delete flatpages in two ways: | 可以用两种方式增加、变更或删除简单页面: | 翻译 | ||
| 328#翻译 | Via the Admin Interface | 通过超级管理界面 | 翻译 | ||
| 330#翻译 | If you've activated the automatic Django admin interface, you should see a Flatpages section on the admin index page. | 如果已经激活了自动的 Django 超级管理界面,你将会在超级管理页面的首页看到有个 Flatpages 区域。 | 翻译 | ||
| 331#翻译 | Edit flatpages as you would edit any other object in the system. | 你可以像编辑系统中其它对象那样编辑简单页面。 | 翻译 | ||
| 333#翻译 | Via the Python API | 通过 Python API | 翻译 | ||
| 335#翻译 | As described previously, flatpages are represented by a standard Django model that lives in <literal>django/contrib/flatpages/models.py</literal> . Hence, you can access flatpage objects via the Django database API, for example: | 前面已经提到,简单页面表现为 <literal>django/contrib/flatpages/models.py</literal> 中的标准 Django 模型。这样,你就可以使用Django数据库API来存取简单页面对象,例如: | 翻译 | ||
| 338#翻译 | Using Flatpage Templates | 使用简单页面模板 | 翻译 | ||
| 340#翻译 | By default, flatpages are rendered via the template <literal>flatpages/default.html</literal> , but you can override that for a particular flatpage with the <literal>template_name</literal> field on the <literal>FlatPage</literal> object. | 缺省情况下,系统使用模板 <literal>flatpages/default.html</literal> 来解析简单页面,但你也可以通过设定 <literal>FlatPage</literal> 对象的 <literal>template_name</literal> 字段来更改特定简单页面的模板。 | 翻译 | ||
| 342#翻译 | Creating the <literal>flatpages/default.html</literal> template is your responsibility. | 你必须自己创建 <literal>flatpages/default.html</literal> 模板。 | 翻译 | ||
| 343#翻译 | In your template directory, just create a <literal>flatpages</literal> directory containing a <literal>default.html</literal> file. | 只需要在模板目录创建一个 <literal>flatpages</literal> 目录,并把 <literal>default.html</literal> 文件置于其中。 | 翻译 | ||
| 345#翻译 | Flatpage templates are passed a single context variable, <literal>flatpage</literal> , which is the flatpage object. | 简单页面模板只接受有一个上下文变量—— <literal>flatpage</literal> ,也就是该简单页面对象。 | 翻译 | ||
| 347#翻译 | Here's a sample <literal>flatpages/default.html</literal> template: | 以下是一个 <literal>flatpages/default.html</literal> 模板范例: | 翻译 | ||
| 350#翻译 | Note that we've used the <literal>safe</literal> template filter to allow <literal>flatpage.content</literal> to include raw HTML and bypass auto-escaping. | 注意我们使用了<literal>safe</literal>模板过滤器来允许<literal>flatpage.content</literal>引入原始HTML而不必转义。 | 翻译 | ||
| 352#翻译 | Redirects | 重定向 | 翻译 | ||
| 354#翻译 | Django's redirects framework lets you manage redirects easily by storing them in a database and treating them as any other Django model object. | 通过将重定向存储在数据库中并将其视为 Django 模型对象,Django 重定向框架让你能够轻松地管理它们。 | 翻译 | ||
| 355#翻译 | For example, you can use the redirects framework to tell Django, Redirect any request to <literal>/music/</literal> to <literal>/sections/arts/music/</literal> . This comes in handy when you need to move things around on your site; Web developers should do whatever is necessary to avoid broken links. | 比如说,你可以通过重定向框架告诉Django,把任何指向 <literal>/music/</literal> 的请求重定向到 <literal>/sections/arts/music/</literal> 。当你需要在站点中移动一些东西时,这项功能就派上用场了——网站开发者应该穷尽一切办法避免出现坏链接。 | 翻译 | ||
| 357#翻译 | Using the Redirects Framework | 使用重定向框架 | 翻译 | ||
| 359#翻译 | To install the redirects application, follow these steps: | 安装重定向应用程序必须遵循以下步骤: | 翻译 | ||
| 361#翻译 | Add <literal>'django.contrib.redirects'</literal> to your <literal>INSTALLED_APPS</literal> . | 将 <literal>'django.contrib.redirects'</literal> 添加到 <literal>INSTALLED_APPS</literal> 设置中。 | 翻译 | ||
| 363#翻译 | Add <literal>'django.contrib.redirects.middleware.RedirectFallbackMiddleware'</literal> to your <literal>MIDDLEWARE_CLASSES</literal> setting. | 将 <literal>'django.contrib.redirects.middleware.RedirectFallbackMiddleware'</literal> 添加到 <literal>MIDDLEWARE_CLASSES</literal> 设置中。 | 翻译 | ||
| 365#翻译 | Run the command <literal>manage.py syncdb</literal> to install the single required table into your database. | 运行 <literal>manage.py syncdb</literal> 命令将所需的表添加到数据库中。 | 翻译 | ||
| 367#翻译 | <literal>manage.py syncdb</literal> creates a <literal>django_redirect</literal> table in your database. | <literal>manage.py syncdb</literal> 在数据库中创建了一个 <literal>django_redirect</literal> 表。 | 翻译 | ||
| 368#翻译 | This is a simple lookup table with <literal>site_id</literal> , <literal>old_path</literal> , and <literal>new_path</literal> fields. | 这是一个简单的查询表,只有<literal>site_id</literal>、old_path和new_path三个字段。 | 翻译 | ||
| 370#翻译 | You can create redirects through either the Django admin interface or the Django database API. | 你可以通过 Django 超级管理界面或者 Django 数据库 API 来创建重定向。 | 翻译 | ||
| 371#翻译 | For more, see the section Adding, Changing, and Deleting Redirects. | 要了解更多信息,请参阅“增加、变更和删除重定向”一节。 | 翻译 | ||
| 373#翻译 | Once you've created redirects, the <literal>RedirectFallbackMiddleware</literal> class does all of the work. | 一旦创建了重定向, <literal>RedirectFallbackMiddleware</literal> 类将完成所有的工作。 | 翻译 | ||
| 374#翻译 | Each time any Django application raises a 404 error, this middleware checks the redirects database for the requested URL as a last resort. | 每当 Django 应用引发一个 404 错误,作为终极手段,该中间件将为所请求的 URL 在重定向数据库中进行查找。 | 翻译 | ||
| 375#翻译 | Specifically, it checks for a redirect with the given <literal>old_path</literal> with a site ID that corresponds to the <literal>SITE_ID</literal> setting. | 确切地说,它将使用给定的 <literal>old_path</literal> 以及 <literal>SITE_ID</literal> 设置对应的站点 ID 查找重定向设置。 | 翻译 | ||
| 376#翻译 | (See the earlier section Sites for more information on <literal>SITE_ID</literal> and the sites framework.) Then it follows these steps: | (查阅前面的“多站点”一节可了解关于 <literal>SITE_ID</literal> 和多站点框架的更多细节) 然后,它将执行以下两个步骤: | 翻译 | ||
| 378#翻译 | If it finds a match, and <literal>new_path</literal> is not empty, it redirects to <literal>new_path</literal> . | 如果找到了匹配项,并且 <literal>new_path</literal> 非空,它将重定向到 <literal>new_path</literal> 。 | 翻译 | ||
| 380#翻译 | If it finds a match, and <literal>new_path</literal> is empty, it sends a 410 (Gone) HTTP header and an empty (contentless) response. | 如果找到了匹配项,但 <literal>new_path</literal> 为空,它将发送一个 410 (Gone) HTTP 头信息以及一个空(无内容)响应。 | 翻译 | ||
| 382#翻译 | If it doesn't find a match, the request continues to be processed as usual. | 如果未找到匹配项,该请求将如常处理。 | 翻译 | ||
| 384#翻译 | The middleware only gets activated for 404 errors not for 500 errors or responses of any other status code. | 该中间件仅为 404 错误激活,而不会为 500 错误或其他任何状态码的响应所激活。 | 翻译 | ||
| 386#翻译 | Note that the order of <literal>MIDDLEWARE_CLASSES</literal> matters. | 注意必须考虑 <literal>MIDDLEWARE_CLASSES</literal> 的顺序。 | 翻译 | ||
| 387#翻译 | Generally, you can put <literal>RedirectFallbackMiddleware</literal> toward the end of the list, because it's a last resort. | 通常,你可以将 <literal>RedirectFallbackMiddleware</literal> 放置在列表的最后,因为它是一种终极手段。 | 翻译 | ||
| 389#翻译 | Note | 注意 | 翻译 | ||
| 391#翻译 | If you're using both the redirect and flatpage fallback middleware, consider which one (redirect or flatpage) you'd like checked first. | 如果同时使用重定向和简单页面回退中间件, 必须考虑先检查其中的哪一个(重定向或简单页面)。 | 翻译 | ||
| 392#翻译 | We suggest flatpages before redirects (thus putting the flatpage middleware before the redirect middleware), but you might feel differently. | 我们建议将简单页面放在重定向之前(因此将简单页面中间件放置在重定向中间件之前),但你可能有不同想法。 | 翻译 | ||
| 394#翻译 | Adding, Changing, and Deleting Redirects | 增加、变更和删除重定向 | 翻译 | ||
| 396#翻译 | You can add, change and delete redirects in two ways: | 你可以两种方式增加、变更和删除重定向: | 翻译 | ||
| 398#翻译 | Via the Admin Interface | 通过管理界面 | 翻译 | ||
| 400#翻译 | If you've activated the automatic Django admin interface, you should see a Redirects section on the admin index page. | 如果已经激活了全自动的 Django 超级管理界面,你应该能够在超级管理首页看到重定向区域。 | 翻译 | ||
| 401#翻译 | Edit redirects as you would edit any other object in the system. | 可以像编辑系统中其它对象一样编辑重定向。 | 翻译 | ||
| 403#翻译 | Via the Python API | 同过Python API | 翻译 | ||
| 405#翻译 | Redirects are represented by a standard Django model that lives in <literal>django/contrib/redirects/models.py</literal> . Hence, you can access redirect objects via the Django database API, for example: | 重定向表现为<literal>django/contrib/redirects/models.py</literal> 中的一个标准 Django 模型。因此,你可以通过Django数据库API来存取重定向对象,例如: | 翻译 | ||
| 408#翻译 | CSRF Protection | CSRF 防护 | 翻译 | ||
| 410#翻译 | The <literal>django.contrib.csrf</literal> package protects against Cross-Site Request Forgery (CSRF). | <literal>django.contrib.csrf</literal> 开发包能够防止遭受跨站请求伪造攻击 (CSRF). | 翻译 | ||
| 412#翻译 | CSRF, also known as session riding, is a Web site security exploit. | CSRF, 又叫会话跳转,是一种网站安全攻击技术。 | 翻译 | ||
| 413#翻译 | It happens when a malicious Web site tricks a user into unknowingly loading a URL from a site at which that user is already authenticated, hence taking advantage of the user's authenticated status. | 当某个恶意网站在用户未察觉的情况下将其从一个已经通过身份验证的站点诱骗至一个新的 URL 时,这种攻击就发生了,因此它可以利用用户已经通过身份验证的状态。 | 翻译 | ||
| 414#翻译 | This can be a bit tricky to understand at first, so we walk through two examples in this section. | 乍一看,要理解这种攻击技术比较困难,因此我们在本节将使用两个例子来说明。 | 翻译 | ||
| 416#翻译 | A Simple CSRF Example | 一个简单的 CSRF 例子 | 翻译 | ||
| 418#翻译 | Suppose you're logged in to a webmail account at <literal>example.com</literal> . This webmail site has a Log Out button that points to the URL <literal>example.com/logout</literal> that is, the only action you need to take in order to log out is to visit the page <literal>example.com/logout</literal> . | 假定你已经登录到 <literal>example.com</literal> 的网页邮件账号。该网站有一个指向<literal>example.com/logout</literal>的注销按钮。就是说,注销其实就是访问<literal>example.com/logout</literal>。 | 翻译 | ||
| 420#翻译 | A malicious site can coerce you to visit the URL <literal>example.com/logout</literal> by including that URL as a hidden <literal><iframe></literal> on its own (malicious) page. | 通过在(恶意)网页上用隐藏一个指向 URL <literal>example.com/logout</literal> 的 <literal><iframe></literal> ,恶意网站可以强迫你访问该 URL 。因此,如果你登录 <literal>example.com</literal> 的网页邮件账号之后,访问了带有指向 <literal>example.com/logout</literal> 之 <literal><iframe></literal> 的恶意站点,访问该恶意页面的动作将使你登出 <literal>example.com</literal> 。 | 翻译 | ||
| 421#翻译 | Thus, if you're logged in to the <literal>example.com</literal> webmail account and visit the malicious page that has an <literal><iframe></literal> to <literal>example.com/logout</literal> , the act of visiting the malicious page will log you out from <literal>example.com</literal> . | 翻译 | 翻译 | ||
| 423#翻译 | Clearly, being logged out of a webmail site against your will is not a terrifying breach of security, but this same type of exploit can happen to <emphasis>any</emphasis> site that trusts users, such as an online banking site or an e-commerce site, where the exploit could be used to initiate an order or payment without the user's knowledge. | 很明显,登出一个邮件网站也不是什么严重的安全问题。但是同样的攻击可能针对任何相信用户的站点,比如在线银行和电子商务网站。这样的话可能在用户不知情的情况下就下订单付款了。 | 翻译 | ||
| 425#翻译 | A More Complex CSRF Example | 稍微复杂一点的CSRF例子 | 翻译 | ||
| 427#翻译 | In the previous example, <literal>example.com</literal> was partially at fault because it allowed a state change (i.e., logging the user out) to be requested via the HTTP <literal>GET</literal> method. | 在上一个例子中, <literal>example.com</literal> 应该负部分责任,因为它允许通过 HTTP <literal>GET</literal> 方法进行状态变更(即登入和登出)。 | 翻译 | ||
| 428#翻译 | It's much better practice to require an HTTP <literal>POST</literal> for any request that changes state on the server. | 如果对服务器的状态变更要求使用 HTTP <literal>POST</literal> 方法,情况就好得多了。 | 翻译 | ||
| 429#翻译 | But even Web sites that require <literal>POST</literal> for state-changing actions are vulnerable to CSRF. | 但是,即便是强制要求使用 <literal>POST</literal> 方法进行状态变更操作也易受到 CSRF 攻击。 | 翻译 | ||
| 431#翻译 | Suppose <literal>example.com</literal> has upgraded its Log Out functionality so that it's a <literal><form></literal> button that is requested via <literal>POST</literal> to the URL <literal>example.com/logout</literal> . Furthermore, the logout <literal><form></literal> includes this hidden field: | 假设 <literal>example.com</literal> 对登出功能进行了升级,登出 <literal><form></literal> 按钮是通过一个指向 URL <literal>example.com/logout</literal> 的 <literal>POST</literal> 动作完成,同时在 <literal><form></literal> 中加入了以下隐藏的字段: | 翻译 | ||
| 434#翻译 | This ensures that a simple <literal>POST</literal> to the URL <literal>example.com/logout</literal> won't log a user out; in order for a user to log out, the user must request <literal>example.com/logout</literal> via <literal>POST</literal> | 这就确保了用简单的指向<literal>example.com/logout</literal>的<literal>POST</literal> 不会让用户登出;要让用户登出,用户必须通过 <literal>POST</literal> 向 <literal>example.com/logout</literal> 发送请求 | 翻译 | ||
| 435#翻译 | <emphasis>and</emphasis> send the <literal>confirm</literal> | 并且发送一个值为'true'的POST变量。 | 翻译 | ||
| 436#翻译 | <literal>POST</literal> variable with a value of <literal>'true'</literal> . | <literal>confirm</literal>。 | 翻译 | ||
| 438#翻译 | Well, despite the extra security, this arrangement can still be exploited by CSRF the malicious page just needs to do a little more work. | 尽管增加了额外的安全机制,这种设计仍然会遭到 CSRF 的攻击——恶意页面仅需一点点改进而已。 | 翻译 | ||
| 439#翻译 | Attackers can create an entire form targeting your site, hide it in an invisible <literal><iframe></literal> , and then use JavaScript to submit that form automatically. | 攻击者可以针对你的站点设计整个表单,并将其藏身于一个不可见的 <literal><iframe></literal> 中,然后使用 Javascript 自动提交该表单。 | 翻译 | ||
| 441#翻译 | Preventing CSRF | 防止 CSRF | 翻译 | ||
| 443#翻译 | How, then, can your site protect itself from this exploit? | 那么,是否可以让站点免受这种攻击呢? | 翻译 | ||
| 444#翻译 | The first step is to make sure all <literal>GET</literal> requests are free of side effects. | 第一步,首先确保所有 <literal>GET</literal> 方法没有副作用。 | 翻译 | ||
| 445#翻译 | That way, if a malicious site includes one of your pages as an <literal><iframe></literal> , it won't have a negative effect. | 这样以来,如果某个恶意站点将你的页面包含为 <literal><iframe></literal> ,它将不会产生负面效果。 | 翻译 | ||
| 447#翻译 | That leaves <literal>POST</literal> requests. | 该技术没有考虑 <literal>POST</literal> 请求。 | 翻译 | ||
| 448#翻译 | The second step is to give each <literal>POST</literal> | 第二步就是给所有 <literal>POST</literal> | 翻译 | ||
| 449#翻译 | <literal><form></literal> a hidden field whose value is secret and is generated from the user's session ID. | 的form标签一个隐藏字段,它的值是保密的并根据用户进程的 ID 生成。 | 翻译 | ||
| 450#翻译 | Then, when processing the form on the server side, check for that secret field and raise an error if it doesn't validate. | 这样,从服务器端访问表单时,可以检查该保密的字段。不吻合时可以引发一个错误。 | 翻译 | ||
| 452#翻译 | This is exactly what Django's CSRF prevention layer does, as explained in the sections that follow. | 这正是 Django CSRF 防护层完成的工作,正如下面的小节所介绍的。 | 翻译 | ||
| 454#翻译 | Using the CSRF Middleware | 使用CSRF中间件 | 翻译 | ||
| 456#翻译 | The <literal>django.contrib.csrf</literal> package contains only one module: | <literal>django.contrib.csrf</literal> 开发包只有一个模块: | 翻译 | ||
| 457#翻译 | <literal>middleware.py</literal> . This module contains a Django middleware class, <literal>CsrfMiddleware</literal> , which implements the CSRF protection. | <literal>middleware.py</literal> 。该模块包含了一个 Django 中间件类—— <literal>CsrfMiddleware</literal> ,该类实现了 CSRF 防护功能。 | 翻译 | ||
| 459#翻译 | To activate this CSRF protection, add <literal>'django.contrib.csrf.middleware.CsrfMiddleware'</literal> to the <literal>MIDDLEWARE_CLASSES</literal> setting in your settings file. | 在设置文件中将 <literal>'django.contrib.csrf.middleware.CsrfMiddleware'</literal> 添加到 <literal>MIDDLEWARE_CLASSES</literal> 设置中可激活 CSRF 防护。 | 翻译 | ||
| 460#翻译 | This middleware needs to process the response <emphasis>after</emphasis> | 该中间件必须在 <literal>SessionMiddleware</literal> | 翻译 | ||
| 461#翻译 | <literal>SessionMiddleware</literal> , so <literal>CsrfMiddleware</literal> must appear <emphasis>before</emphasis> | <emphasis>之后</emphasis> 执行,因此在列表中 <literal>CsrfMiddleware</literal> 必须出现在 <literal>SessionMiddleware</literal> | 翻译 | ||
| 462#翻译 | <literal>SessionMiddleware</literal> in the list (because the response middleware is processed last-to-first). | <emphasis>之前</emphasis> (因为响应中间件是自后向前执行的)。 | 翻译 | ||
| 463#翻译 | Also, it must process the response before the response gets compressed or otherwise mangled, so <literal>CsrfMiddleware</literal> must come after <literal>GZipMiddleware</literal> . Once you've added that to your <literal>MIDDLEWARE_CLASSES</literal> setting, you're done. | 同时,它也必须在响应被压缩或解压之前对响应结果进行处理,因此 <literal>CsrfMiddleware</literal> 必须在 <literal>GZipMiddleware</literal> 之后执行。一旦将它添加到<literal>MIDDLEWARE_CLASSES</literal>设置中,你就完成了工作。 | 翻译 | ||
| 464#翻译 | See the section Order of MIDDLEWARE_CLASSES in Chapter 15 for more explanation. | 参见第十五章的“MIDDLEWARE_CLASSES顺序”小节以了解更多。 | 翻译 | ||
| 466#翻译 | In case you're interested, here's how <literal>CsrfMiddleware</literal> works. | 如果感兴趣的话,下面是 <literal>CsrfMiddleware</literal> 的工作模式。 | 翻译 | ||
| 467#翻译 | It does these two things: | 它完成以下两项工作: | 翻译 | ||
| 469#翻译 | It modifies outgoing requests by adding a hidden form field to all <literal>POST</literal> forms, with the name <literal>csrfmiddlewaretoken</literal> and a value that is a hash of the session ID plus a secret key. | 它修改当前处理的请求,向所有的 <literal>POST</literal> 表单增添一个隐藏的表单字段,使用名称是 <literal>csrfmiddlewaretoken</literal> ,值为当前会话 ID 加上一个密钥的散列值。 | 翻译 | ||
| 470#翻译 | The middleware does <emphasis>not</emphasis> modify the response if there's no session ID set, so the performance penalty is negligible for requests that don't use sessions. | 如果未设置会话 ID ,该中间件将 <emphasis>不会</emphasis> 修改响应结果,因此对于未使用会话的请求来说性能损失是可以忽略的。 | 翻译 | ||
| 472#翻译 | On all incoming <literal>POST</literal> requests that have the session cookie set, it checks that <literal>csrfmiddlewaretoken</literal> is present and correct. | 对于所有含会话 cookie 集合的传入 <literal>POST</literal> 请求,它将检查是否存在 <literal>csrfmiddlewaretoken</literal> 及其是否正确。 | 翻译 | ||
| 473#翻译 | If it isn't, the user will get a 403 <literal>HTTP</literal> error. | 如果不是的话,用户将会收到一个 403 <literal>HTTP</literal> 错误。 | 翻译 | ||
| 474#翻译 | The content of the 403 error page is the message Cross Site Request Forgery detected. | 403 错误页面的内容是检测到了跨域请求伪装。 | 翻译 | ||
| 475#翻译 | Request aborted. | 终止请求。 | 翻译 | ||
| 477#翻译 | This ensures that only forms originating from your Web site can be used to POST data back. | 该步骤确保只有源自你的站点的表单才能将数据 POST 回来。 | 翻译 | ||
| 479#翻译 | This middleware deliberately targets only HTTP <literal>POST</literal> requests (and the corresponding POST forms). | 该中间件特意只针对 HTTP <literal>POST</literal> 请求(以及对应的 POST 表单)。 | 翻译 | ||
| 480#翻译 | As we explained, <literal>GET</literal> requests ought never to have side effects; it's your own responsibility to ensure this. | 如我们所解释的,永远不应该因为使用了 <literal>GET</literal> 请求而产生负面效应,你必须自己来确保这一点。 | 翻译 | ||
| 482#翻译 | <literal>POST</literal> requests not accompanied by a session cookie are not protected, but they don't <emphasis>need</emphasis> to be protected, because a malicious Web site could make these kind of requests anyway. | 未使用会话 cookie 的 <literal>POST</literal> 请求无法受到保护,但它们也不 <emphasis>需要</emphasis> 受到保护,因为恶意网站可用任意方法来制造这种请求。 | 翻译 | ||
| 484#翻译 | To avoid altering non-HTML requests, the middleware checks the response's <literal>Content-Type</literal> header before modifying it. | 为了避免转换非 HTML 请求,中间件在编辑响应结果之前对它的 <literal>Content-Type</literal> 头标进行检查。 | 翻译 | ||
| 485#翻译 | Only pages that are served as <literal>text/html</literal> or <literal>application/xml+xhtml</literal> are modified. | 只有标记为 <literal>text/html</literal> 或 <literal>application/xml+xhtml</literal> 的页面才会被修改。 | 翻译 | ||
| 487#翻译 | Limitations of the CSRF Middleware | CSRF中间件的局限性 | 翻译 | ||
| 489#翻译 | <literal>CsrfMiddleware</literal> requires Django's session framework to work. | <literal>CsrfMiddleware</literal> 的运行需要 Django 的会话框架。 | 翻译 | ||
| 490#翻译 | (See Chapter 14 for more on sessions.) If you're using a custom session or authentication framework that manually manages session cookies, this middleware will not help you. | (参阅第 14 章了解更多关于会话的内容。)如果你使用了自定义会话或者身份验证框架手动管理会话 cookies,该中间件将帮不上你的忙。 | 翻译 | ||
| 492#翻译 | If your application creates HTML pages and forms in some unusual way (e.g., if it sends fragments of HTML in JavaScript <literal>document.write</literal> statements), you might bypass the filter that adds the hidden field to the form. | 如果你的应用程序以某种非常规的方法创建 HTML 页面(例如:在 Javascript 的<literal>document.write</literal>语句中发送 HTML 片段),你可能会绕开了向表单添加隐藏字段的过滤器。 | 翻译 | ||
| 493#翻译 | In this case, the form submission will always fail. | 在此情况下,表单提交永远无法成功。 | 翻译 | ||
| 494#翻译 | (This happens because <literal>CsrfMiddleware</literal> uses a regular expression to add the <literal>csrfmiddlewaretoken</literal> field to your HTML before the page is sent to the client, and the regular expression sometimes cannot handle wacky HTML.) If you suspect this might be happening, just view the source in your Web browser to see whether <literal>csrfmiddlewaretoken</literal> was inserted into your <literal><form></literal> . | (这是因为在页面发送到客户端之前,<literal>CsrfMiddleware</literal>使用正则表达式来添加<literal>csrfmiddlewaretoken</literal>字段到你的HTML中,而正则表达式不能处理不规范的HTML。)如果你怀疑出现了这样的问题。使用你浏览器的查看源代码功能以确定<literal>csrfmiddlewaretoken</literal>是否插入到了表单中。 | 翻译 | ||
| 496#翻译 | For more CSRF information and examples, visit <reference name="http://en.wikipedia.org/wiki/CSRF" refuri="http://en.wikipedia.org/wiki/CSRF">http://en.wikipedia.org/wiki/CSRF</reference> | 想了解更多关于 CSRF 的信息和例子的话,可以访问 <reference name="http://en.wikipedia.org/wiki/CSRF" refuri="http://en.wikipedia.org/wiki/CSRF">http://en.wikipedia.org/wiki/CSRF</reference> 。 | 翻译 | ||
| 498#翻译 | Humanizing Data | 人性化数据 | 翻译 | ||
| 500#翻译 | The package <literal>django.contrib.humanize</literal> holds a set of Django template filters useful for adding a human touch to data. | 包<literal>django.contrib.humanize</literal>包含了一些是数据更人性化的模板过滤器。 | 翻译 | ||
| 501#翻译 | To activate these filters, add <literal>'django.contrib.humanize'</literal> to your <literal>INSTALLED_APPS</literal> . Once you've done that, use <literal>{% load humanize %}</literal> in a template, and you'll have access to the filters described in the following sections. | 要激活这些过滤器,请把<literal>'django.contrib.humanize'</literal>加入到你的<literal>INSTALLED_APPS</literal>中。完成之后,向模版了加入<literal>{% load humanize %}</literal>就可以使用下面的过滤器了。 | 翻译 | ||
| 503#翻译 | apnumber | apnumber | 翻译 | ||
| 505#翻译 | For numbers 1 through 9, this filter returns the number spelled out. | 对于 1 到 9 的数字,该过滤器返回了数字的拼写形式。 | 翻译 | ||
| 506#翻译 | Otherwise, it returns the numeral. | 否则,它将返回数字。 | 翻译 | ||
| 507#翻译 | This follows Associated Press style. | 这遵循的是美联社风格。 | 翻译 | ||
| 509#翻译 | Examples: | 举例: | 翻译 | ||
| 511#翻译 | 1 becomes one. | 1 变成 one 。 | 翻译 | ||
| 513#翻译 | 2 becomes two. | 2 变成 two 。 | 翻译 | ||
| 515#翻译 | 10 becomes 10. | 10 变成 10 。 | 翻译 | ||
| 517#翻译 | You can pass in either an integer or a string representation of an integer. | 你可以传入一个整数或者表示整数的字符串。 | 翻译 | ||
| 519#翻译 | intcomma | intcomma | 翻译 | ||
| 521#翻译 | This filter converts an integer to a string containing commas every three digits. | 该过滤器将整数转换为每三个数字用一个逗号分隔的字符串。 | 翻译 | ||
| 523#翻译 | Examples: | 例子: | 翻译 | ||
| 525#翻译 | 4500 becomes 4,500. | 4500 变成 4,500 。 | 翻译 | ||
| 527#翻译 | 45000 becomes 45,000. | 45000 变成 45,000 。 | 翻译 | ||
| 529#翻译 | 450000 becomes 450,000. | 450000 变成 450,000 。 | 翻译 | ||
| 531#翻译 | 4500000 becomes 4,500,000. | 4500000 变成 4,500,000 。 | 翻译 | ||
| 533#翻译 | You can pass in either an integer or a string representation of an integer. | 可以传入整数或者表示整数的字符串。 | 翻译 | ||
| 535#翻译 | intword | intword | 翻译 | ||
| 537#翻译 | This filter converts a large integer to a friendly text representation. | 该过滤器将一个很大的整数转换成友好的文本表示方式。 | 翻译 | ||
| 538#翻译 | It works best for numbers over 1 million. | 它对于超过一百万的数字最好用。 | 翻译 | ||
| 540#翻译 | Examples: | 例子: | 翻译 | ||
| 542#翻译 | 1000000 becomes 1.0 million. | 1000000 变成 1.0 million 。 | 翻译 | ||
| 544#翻译 | 1200000 becomes 1.2 million. | 1200000 变成 1.2 million 。 | 翻译 | ||
| 546#翻译 | 1200000000 becomes 1.2 billion. | 1200000000 变成 1.2 billion 。 | 翻译 | ||
| 548#翻译 | Values up to 1 quadrillion (1,000,000,000,000,000) are supported. | 最大支持不超过一千的五次方(1,000,000,000,000,000)。 | 翻译 | ||
| 550#翻译 | You can pass in either an integer or a string representation of an integer. | 可以传入整数或者表示整数的字符串。 | 翻译 | ||
| 552#翻译 | ordinal | ordinal | 翻译 | ||
| 554#翻译 | This filter converts an integer to its ordinal as a string. | 该过滤器将整数转换为序数词的字符串形式。 | 翻译 | ||
| 556#翻译 | Examples: | 例子: | 翻译 | ||
| 558#翻译 | 1 becomes 1st. | 1 变成 1st 。 | 翻译 | ||
| 560#翻译 | 2 becomes 2nd. | 2 变成 2nd 。 | 翻译 | ||
| 562#翻译 | 3 becomes 3rd. | 3 变成 3rd 。 | 翻译 | ||
| 564#翻译 | 254 becomes 254th. | 254变成254th。 | 翻译 | ||
| 566#翻译 | You can pass in either an integer or a string representation of an integer. | 可以传入整数或者表示整数的字符串。 | 翻译 | ||
| 568#翻译 | Markup Filters | 标记过滤器 | 翻译 | ||
| 570#翻译 | The package <literal>django.contrib.markup</literal> includes a handful of Django template filters, each of which implements a common markup languages: | 包<literal>django.contrib.markup</literal>包含了一些列Django模板过滤器,每一个都实现了一中通用的标记语言。 | 翻译 | ||
| 572#翻译 | <literal>textile</literal> : Implements Textile (<reference name="http://en.wikipedia.org/wiki/Textile_%28markup_language%29" refuri="http://en.wikipedia.org/wiki/Textile_%28markup_language%29">http://en.wikipedia.org/wiki/Textile_%28markup_language%29</reference>) | <literal>textile</literal> : 实现了 Textile (<reference name="http://en.wikipedia.org/wiki/Textile_%28markup_language%29" refuri="http://en.wikipedia.org/wiki/Textile_%28markup_language%29">http://en.wikipedia.org/wiki/Textile_%28markup_language%29</reference>) | 翻译 | ||
| 574#翻译 | <literal>markdown</literal> : Implements Markdown (<reference name="http://en.wikipedia.org/wiki/Markdown" refuri="http://en.wikipedia.org/wiki/Markdown">http://en.wikipedia.org/wiki/Markdown</reference>) | <literal>markdown</literal> : 实现了 Markdown (<reference name="http://en.wikipedia.org/wiki/Markdown" refuri="http://en.wikipedia.org/wiki/Markdown">http://en.wikipedia.org/wiki/Markdown</reference>) | 翻译 | ||
| 576#翻译 | <literal>restructuredtext</literal> : Implements ReStructured Text (<reference name="http://en.wikipedia.org/wiki/ReStructuredText" refuri="http://en.wikipedia.org/wiki/ReStructuredText">http://en.wikipedia.org/wiki/ReStructuredText</reference>) | <literal>restructuredtext</literal> : 实现了 ReStructured Text (<reference name="http://en.wikipedia.org/wiki/ReStructuredText" refuri="http://en.wikipedia.org/wiki/ReStructuredText">http://en.wikipedia.org/wiki/ReStructuredText</reference>) | 翻译 | ||
| 578#翻译 | In each case, the filter expects formatted markup as a string and returns a string representing the marked-up text. | 每种情形下,过滤器都期望字符串形式的格式化标记,并返回表示标记文本的字符串。 | 翻译 | ||
| 579#翻译 | For example, the <literal>textile</literal> filter converts text that is marked up in Textile format to HTML: | 例如:<literal>textile</literal>过滤器吧Textile格式的文本转换为HTML。 | 翻译 | ||
| 582#翻译 | To activate these filters, add <literal>'django.contrib.markup'</literal> to your <literal>INSTALLED_APPS</literal> setting. | 要激活这些过滤器,仅需将 <literal>'django.contrib.markup'</literal> 添加到 <literal>INSTALLED_APPS</literal> 设置中。 | 翻译 | ||
| 583#翻译 | Once you've done that, use <literal>{% load markup %}</literal> in a template, and you'll have access to these filters. | 一旦完成了该项工作,在模板中通过 <literal>{% load markup %}</literal> 就能使用这些过滤器。 | 翻译 | ||
| 584#翻译 | For more documentation, read the source code in <literal>django/contrib/markup/templatetags/markup.py.</literal> | 要想掌握更多信息的话,可阅读 <literal>django/contrib/markup/templatetags/markup.py.</literal> 内的源代码。 | 翻译 | ||
| 586#翻译 | What's Next? | 下一章 | 翻译 | ||
| 588#翻译 | Many of these contributed frameworks (CSRF, the auth system, etc.) do their magic by providing a piece of <emphasis>middleware</emphasis> . Middleware is code that runs before and/or after every request and can modify requests and responses at will, to extend the framework. | 这些继承框架(CSRF、身份验证系统等等)通过提供 <emphasis>中间件</emphasis> 来实现其奇妙的功能。中间件是在请求之前/后执行的可以修改请求和响应的代码,它扩展了框架。 | 翻译 | ||
| 589#翻译 | In the <reference name="next chapter" refuri="../chapter17/">next chapter</reference>, we'll discuss Django's built-in middleware and explain how you can write your own. | 在下一章,我们将介绍Django的中间件并解释怎样写出自己的中间件。 | 翻译 | ||
| 591#翻译 | under the <reference name="GNU Free Document License" refuri="/license/">GNU Free Document License</reference>. | 受<reference name="GNU Free Document License" refuri="/license/">GNU Free Document License</reference>约束。 | 翻译 | ||
| 592#翻译 | Hosting graciously provided by | 谨奉 | 翻译 |