Django 简明教程

Django - Caching

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

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 缓存框架的一个优点是可以缓存 −

  1. 特定视图的输出。

  2. 模板的一部分。

  3. Your entire site.

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

Setting Up Cache in Database

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

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

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

python manage.py createcachetable

Setting Up Cache in File System

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

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

Setting Up Cache in Memory

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

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

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 选项来完成。需要添加到该选项中的内容如下 −

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

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

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

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 视图的结果 −

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 分钟。

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

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 分开缓存。

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

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 中不再需要它了。

Caching a Template Fragment

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

{% 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 %}

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

{% 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 标记需要两个参数 − 希望块被缓存的时间(以秒为单位)以及给缓存片段的名称。