Django 简明教程

Django - Caching

缓存是指保存昂贵计算的结果,以便在下次需要时无需再执行计算。以下是一个解释缓存工作原理的伪代码 −

To cache something is to save the result of an expensive calculation, so that you don’t perform it the next time you need it. Following is a pseudo code that explains how caching works −

given a URL, try finding that page in the cache

if the page is in the cache:
   return the cached page
else:
   generate the page
   save the generated page in the cache (for next time)
   return the generated page

Django 自带缓存系统,可以用来保存动态页面,从而避免在需要时再次计算。Django 缓存框架的一个优点是可以缓存 −

Django comes with its own caching system that lets you save your dynamic pages, to avoid calculating them again when needed. The good point in Django Cache framework is that you can cache −

  1. The output of a specific view.

  2. A part of a template.

  3. Your entire site.

要在 Django 中使用缓存,首先需要设置缓存的存放位置。缓存框架提供了多种可能选项 - 可以将缓存保存到数据库、文件系统或直接保存在内存中。设置在项目的 settings.py 文件中完成。

To use cache in Django, first thing to do is to set up where the cache will stay. The cache framework offers different possibilities - cache can be saved in database, on file system or directly in memory. Setting is done in the settings.py file of your project.

Setting Up Cache in Database

只需在项目 settings.py 文件中添加以下内容 −

Just add the following in the project settings.py file −

CACHES = {
   'default': {
      'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
      'LOCATION': 'my_table_name',
   }
}

要使此设置起作用并完成设置,我们需要创建名为`my_table_name`的缓存表。为此,你需要执行以下操作 −

For this to work and to complete the setting, we need to create the cache table 'my_table_name'. For this, you need to do the following −

python manage.py createcachetable

Setting Up Cache in File System

只需在项目 settings.py 文件中添加以下内容 −

Just add the following in the project settings.py file −

CACHES = {
   'default': {
      'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
      'LOCATION': '/var/tmp/django_cache',
   }
}

Setting Up Cache in Memory

这是最有效的缓存方式,要使用它,你可以根据为内存缓存选择的 Python 绑定库使用以下选项之一 −

This is the most efficient way of caching, to use it you can use one of the following options depending on the Python binding library you choose for the memory cache −

CACHES = {
   'default': {
      'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
      'LOCATION': '127.0.0.1:11211',
   }
}

Or

Or

CACHES = {
   'default': {
      'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
      'LOCATION': 'unix:/tmp/memcached.sock',
   }
}

Caching the Entire Site

在 Django 中使用缓存最简单的方式是缓存整个站点。这可以通过编辑 project settings.py 中的 MIDDLEWARE_CLASSES 选项来完成。需要添加到该选项中的内容如下 −

The simplest way of using cache in Django is to cache the entire site. This is done by editing the MIDDLEWARE_CLASSES option in the project settings.py. The following need to be added to the option −

MIDDLEWARE_CLASSES += (
   'django.middleware.cache.UpdateCacheMiddleware',
   'django.middleware.common.CommonMiddleware',
   'django.middleware.cache.FetchFromCacheMiddleware',
)

请注意,这里的顺序很重要,更新应在获取中间件之前。

Note that the order is important here, Update should come before Fetch middleware.

然后在同一文件中,你需要设置 −

Then in the same file, you need to set −

CACHE_MIDDLEWARE_ALIAS – The cache alias to use for storage.
CACHE_MIDDLEWARE_SECONDS – The number of seconds each page should be cached.

Caching a View

如果你不想缓存整个站点,可以缓存一个特定视图。这可以通过使用 Django 提供的 cache_page 装饰器来完成。假设我们要缓存 viewArticles 视图的结果 −

If you don’t want to cache the entire site you can cache a specific view. This is done by using the cache_page decorator that comes with Django. Let us say we want to cache the result of the viewArticles view −

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)

def viewArticles(request, year, month):
   text = "Displaying articles of : %s/%s"%(year, month)
   return HttpResponse(text)

正如你所见, cache_page 将视图结果缓存的时间作为参数。在我们上面的示例中,结果将缓存 15 分钟。

As you can see cache_page takes the number of seconds you want the view result to be cached as parameter. In our example above, the result will be cached for 15 minutes.

Note − 如上所述,以上视图映射到 −

Note − As we have seen before the above view was map to −

urlpatterns = patterns('myapp.views',
   url(r'^articles/(?P<month>\d{2})/(?P<year>\d{4})/', 'viewArticles', name = 'articles'),)

由于 URL 接受参数,每一次不同的调用将被分别缓存。例如,对 /myapp/articles/02/2007 的请求将与 /myapp/articles/03/2008 分开缓存。

Since the URL is taking parameters, each different call will be cached separately. For example, request to /myapp/articles/02/2007 will be cached separately to /myapp/articles/03/2008.

还可以在 url.py 文件中直接缓存视图。以下是生成与上述相同结果的操作。只需编辑 myapp/url.py 文件,并将相关的映射 URL(上面)改成 −

Caching a view can also directly be done in the url.py file. Then the following has the same result as the above. Just edit your myapp/url.py file and change the related mapped URL (above) to be −

urlpatterns = patterns('myapp.views',
   url(r'^articles/(?P<month>\d{2})/(?P<year>\d{4})/',
   cache_page(60 * 15)('viewArticles'), name = 'articles'),)

当然,在 myapp/views.py 中不再需要它了。

And, of course, it’s no longer needed in myapp/views.py.

Caching a Template Fragment

你也可以使用 cache 标记缓存模板部分。我们使用 hello.html 模板来做演示 −

You can also cache parts of a template, this is done by using the cache tag. Let’s take our hello.html template −

{% extends "main_template.html" %}
{% block title %}My Hello Page{% endblock %}
{% block content %}

Hello World!!!<p>Today is {{today}}</p>
We are
{% if today.day == 1 %}

the first day of month.
{% elif today == 30 %}

the last day of month.
{% else %}

I don't know.
{%endif%}

<p>
   {% for day in days_of_week %}
   {{day}}
</p>

{% endfor %}
{% endblock %}

为了缓存内容块,我们的模板将变成 −

And to cache the content block, our template will become −

{% load cache %}
{% extends "main_template.html" %}
{% block title %}My Hello Page{% endblock %}
{% cache 500 content %}
{% block content %}

Hello World!!!<p>Today is {{today}}</p>
We are
{% if today.day == 1 %}

the first day of month.
{% elif today == 30 %}

the last day of month.
{% else %}

I don't know.
{%endif%}

<p>
   {% for day in days_of_week %}
   {{day}}
</p>

{% endfor %}
{% endblock %}
{% endcache %}

如你所见,cache 标记需要两个参数 − 希望块被缓存的时间(以秒为单位)以及给缓存片段的名称。

As you can see above, the cache tag will take 2 parameters − the time you want the block to be cached (in seconds) and the name to be given to the cache fragment.