Django使用缓存笔记

Django设置缓存需要在settings.py文件中进行设置,缓存配置是通过setting文件的CACHES 配置来实现的。 

Memcached

需要在Django中使用Memcached时:
将 BACKEND 设置为django.core.cache.backends.memcached.MemcachedCache或者django.core.cache.backends.memcached.PyLibMCCache (取决于你所选绑定memcached的方式)
将LOCATION设置为ip:port值,ip是Memcached守护进程的ip地址,port是Memcached运行的端口。或者设置为unix:path值,path是Memcached Unix socket file的路径.
在这个例子中,Memcached 运行再 本地 (127.0.0.1) 的11211端口,使用 python-memcached(也就是需要这么一个python插件) 绑定:

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

这个例子中,Memcached 通过一个本地的Unix socket file/tmp/memcached.sock 来交互,也要使用python-memcached绑定:

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

Memcached有一个非常好的特点就是可以让几个服务的缓存共享。 这就意味着你可以再几个物理机上运行Memcached服务,这些程序将会把这几个机器当做 同一个 缓存,从而不需要复制每个缓存的值在每个机器上。为了使用这个特性,把所有的服务地址放在LOCATION里面,用分号隔开或者当做一个list。

这个例子,缓存共享在2个Memcached 实例中,IP地址为172.19.26.240 和 172.19.26.242,端口同为11211:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': [
            '172.19.26.240:11211',
            '172.19.26.242:11211',
        ],
        'options': {
            'MAX_ENTRIES': 10240,
        },
    }
}

下面的这个例子,缓存通过下面几个  Memcached 实例共享,IP地址为172.19.26.240 (端口 11211), 172.19.26.242 (端口 11212), and 172.19.26.244 (端口 11213):

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': [
            '172.19.26.240:11211',
            '172.19.26.242:11212',
            '172.19.26.244:11213',
        ],
        'options': {
            'MAX_ENTRIES': 10240,
        },
    }
}

数据库缓存

Django可以把缓存保存在你的数据库里。如果你有一个快速的、专业的数据库服务器的话那这种方式是效果最好的。
为了把数据表用来当做你的缓存后台:
把BACKEND设置为django.core.cache.backends.db.DatabaseCache
把 LOCATION 设置为 tablename, 数据表的名称。这个名字可以是任何你想要的名字,只要它是一个合法的表名并且在你的数据库中没有被使用过。
在这个示例中,缓存表的名字是 my_cache_table:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'my_cache_table',
        'options': {
            'MAX_ENTRIES': 10240,
        },
    }
}

创建缓存表

使用数据库缓存之前,你必须用这个命令来创建缓存表:

python manage.py createcachetable

这将在你的数据库中创建一个Django的基于数据库缓存系统预期的特定格式的数据表。

本地内存缓存

这是默认的缓存,如果你不在指定其他的缓存设置。如果你想要具有高速这个有点的基于内存的缓存但是又没有能力带动 Memcached, 那就考虑一下本地缓存吧。这个缓存是per-process(见下文)和线程安全的。要使用它,请将BACKEND设置为"django.core.cache.backends.locmem.LocMemCache"。例如:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
        'options': {
            'MAX_ENTRIES': 10240,
        },
    }
}

高速缓存LOCATION用于标识各个存储器存储。如果您只有一个locmem快取,可以省略LOCATION;然而,如果您有多个本地内存缓存,您将需要为其中至少一个分配一个名称,以保持它们分离。
注意每个进程都有自己的私有缓存实例,这意味着不可能有跨进程缓存。这显然也意味着本地内存缓存不是特别高效的内存,因此它可能不是生产环境的好选择。

Cache 参数

TIMEOUT

缓存的默认过期时间,以秒为单位,这个参数默认是300seconds (5 分钟).

你可以设置TIMEOUT为None这样的话,缓存默认永远不会过期。值设置成0造成缓存立即失效(缓存就没有意义了)。

OPTIONS

这个参数应该被传到缓存后端。有效的可选项列表根据缓存的后端不同而不同,由第三方库所支持的缓存将会把这些选项直接配置到底层的缓存库。

缓存的后端实现自己的选择策略,常见的选项:

MAX_ENTRIES

高速缓存允许的最大条目数,超出这个数则旧值将被删除. 这个参数默认是300.

CULL_FREQUENCY

当达到MAX_ENTRIES的时候,被删除的条目比率。实际比率是1/CULL_FREQUENCY,所以设置CULL_FREQUENCY为2会在达到MAX_ENTRIES 所设置值时删去一半的缓存。这个参数应该是整数,默认为 3.

把 CULL_FREQUENCY的值设置为 0 意味着当达到MAX_ENTRIES时,缓存将被清空。某些缓存后端 (database尤其)这将以很多缓存丢失为代价,大大much 提高接受访问的速度。

KEY_PREFIX

将自动包含(默认情况下预置为)Django服务器使用的所有缓存键的字符串。

VERSION

由Django服务器生成的缓存键的默认版本号。

KEY_FUNCTION

包含函数的虚线路径的字符串,定义如何将前缀,版本和键组成最终缓存键。

在下面这个例子中,一个文件系统缓存后端,缓存过期时间被设置为60秒,最大条目为1000.

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

站点级缓存

一旦高速缓存设置,最简单的方法是使用缓存缓存整个网站。你需要把'django.middleware.cache.UpdateCacheMiddleware' 和 'django.middleware.cache.FetchFromCacheMiddleware' 添加到你的MIDDLEWARE_CLASSES设置里, 如例子所示:

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

'update'中间件,必须放在列表的开始位置,而fectch中间件,必须放在最后。
然后,添加下面这些需要的参数到settings文件里:

CACHE_MIDDLEWARE_ALIAS

用于存储的缓存的别名

CACHE_MIDDLEWARE_SECONDS

每个page需要被缓存多少秒

CACHE_MIDDLEWARE_KEY_PREFIX

如果缓存被使用相同Django安装的多个网站所共享,那么把这个值设成当前网站名,或其他能代表这个Django实例的唯一字符串,以避免key发生冲突。 如果你不在意的话可以设成空字符串。

FetchFromCacheMiddleware缓存GET和HEAD状态为200的回应,用不同的参数请求相同的url被视为独立的页面,缓存是分开的。

另外, UpdateCacheMiddleware在每个HttpResponse里自动设置了一些头部信息
设置Last-Modified 当一个新(没缓存的)版本的页面被请求时,为当前日期/时间
设置 Expires 头 为当前日期/时间加上定义的CACHE_MIDDLEWARE_SECONDS.
设置 Cache-Control头部来给页面一个最长的有效期, 来自 CACHE_MIDDLEWARE_SECONDS 的设置.

单个view缓存

django.views.decorators.cache.cache_page()

更加轻巧的缓存框架使用方法是对单个有效视图的输出进行缓存。 django.views.decorators.cache 定义了一个自动缓存视图响应的 cache_page装饰器,使用非常简单:

from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
    ...

cache_page接受一个参数:timeout,秒为单位。在前例中,“my_view()”视图的结果将被缓存15分钟(注意为了提高可读性我们写了60 * 15等于 900也就是说15分钟等于60秒乘15.)
和站点缓存一样,视图缓存与 URL 无关。如果多个URL指向同一视图,每个URL将会分别缓存。

在URLconf中指定每个视图的缓存

将视图硬编码为使用缓存,因为cache_page在适当的位置对my_view函数进行了转换。该方法将视图与缓存系统进行了耦合,从几个方面来说并不理想。例如,你可能想在某个无缓存的站点中重用该视图函数,或者不想通过缓存使用页面的人请求你的页面。解决这些问题的方法是在URLconf 中指定视图缓存,而不是在这些视图函数上来指定。

这样做很容易:在URLconf中引用它时,只需用cache_page包装视图函数。这是以前的URLconf:
my_view包裹在cache_page:

from django.views.decorators.cache import cache_page

urlpatterns = [
    url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
]

模板片段缓存

如果想对缓存进行更多的控制,可以使用 cache模板标签来缓存模板的一个片段。 要让模板处理这个标签,把{% load cache %} 放在缓存片段的上面。

标签{% cache %}将按给定的时间缓存包含块中的内容。它最少需要两个参数:缓存时间(以秒为单位);给缓存片段起的名称。例如:

{% load cache %}
{% cache 500 sidebar %}
    .. sidebar ..
{% endcache %}

有时,你可以依据这个片段内的动态内容缓存多个版本。如上个例子中,可以给站点的每个用户生成不同版本的sidebar缓存。只需要给 {% cache %}标签再传递一个参数来标识区分这个缓存片段。

{% load cache %}
{% cache 500 sidebar request.user.username %}
    .. sidebar for logged in user ..
{% endcache %}

指定一个以上的参数来识别片段是非常好的。 简单的尽可能的传递你需要的参数到 {% cache %} 。

如果USE_I18N设置为True,则每个网站中间件缓存将respect the active language。对于cache模板标记,您可以使用模板中提供的translation-specific variables之一来实现相同的结果:

{% load i18n %}
{% load cache %}

{% get_current_language as LANGUAGE_CODE %}

{% cache 600 welcome LANGUAGE_CODE %}
    {% trans "Welcome to example.com" %}
{% endcache %}

缓存超时可以是模板变量,只要模板变量解析为整数值即可。例如,如果模板变量my_timeout设置为值600,则以下两个示例是等效的:

{% cache 600 sidebar %} ... {% endcache %}
{% cache my_timeout sidebar %} ... {% endcache %}

此功能有助于避免模板中的重复。您可以在一个位置设置变量的超时,只需重复使用该值。

底层的缓存API

对于这个情况 Django提供了一个底层的 cache API. 你可以用这个 API来储存在缓存中的对象,并且控制粒度随你喜欢。您可以缓存可以安全pickle的任何Python对象:模型对象的字符串,字典,列表等等。 
访问缓存

django.core.cache.caches
>>> from django.core.cache import caches
>>> cache1 = caches['myalias']
>>> cache2 = caches['myalias']
>>> cache1 is cache2
True

如果key不存在,就会引发一个 InvalidCacheBackendError 。

基本用法

>>> cache.set('my_key', 'hello, world!', 30)
>>> cache.get('my_key')
'hello, world!'

timeout参数是可选的,默认为CACHES设置中适当后端的timeout参数(如上所述)。它是值应该存储在缓存中的秒数。0的timeout将不会缓存该值。

如果对象不存在于缓存中,则cache.get()返回None:

# 等30秒后

>>> cache.get('my_key')
None

我们建议不要在缓存中存储文本值None,因为您将无法区分您存储的None值和由返回值表示的缓存未命中None。

cache.get()可以采用default参数。如果对象不存在于缓存中,则指定返回哪个值:

>>> cache.get('my_key', 'has expired')
'has expired'

要添加键(如果它尚不存在),请使用add()方法。它使用与set()相同的参数,但如果指定的键已经存在,它不会尝试更新缓存:

>>> cache.set('add_key', 'Initial value')
>>> cache.add('add_key', 'New value')
>>> cache.get('add_key')
'Initial value'

如果你需要知道add()是否在缓存中存储了一个值,你可以检查返回值。如果值存储,则返回True,否则返回False。

还有一个get_many()接口,只会命中一次缓存。get_many()返回一个字典,其中包含您请求的所有实际存在于缓存中的键(并且未过期):

>>> cache.set('a', 1)
>>> cache.set('b', 2)
>>> cache.set('c', 3)
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}

要更有效地设置多个值,请使用set_many()传递键值对的字典:

>>> cache.set_many({'a': 1, 'b': 2, 'c': 3})
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}

像cache.set(),set_many()采用可选的timeout参数。

您可以使用delete()显式删除键。这是清除特定对象的缓存的简单方法:

>>> cache.delete('a')

如果您想一次清除一堆键,delete_many()可以取得要清除的键列表:

>>> cache.delete_many(['a', 'b', 'c'])

最后,如果要删除缓存中的所有键,请使用cache.clear()。小心这个;clear()将从缓存中删除所有,而不仅仅是应用程序设置的键。

>>> cache.clear()

实例:

settings.py文件的设置

# cache配置#########################################
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
        'options': {
            'MAX_ENTRIES': 10240,
        }
    },
    'memcache': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        # 'LOCATION': 'unix:/home/billvsme/memcached.sock',
        'LOCATION': '127.0.0.1:11211',
        'options': {
            'MAX_ENTRIES': 10240,
        }
    },
}

views.py代码开始获取缓存

# 缓存
try:
    cache = caches['memcache']
except ImportError as e:
    cache = caches['default']

单个函数使用

@api_view(['GET'])
@cache_page(60 * 15)
def tags_list(request):
    """
    使用装饰器进行相关操作
    :param request:
    :return:
    """
    tags = Tag.objects.all()
    if tags:
        serializer = TagSerializer(tags, many=True)
        return Response(serializer.data)
    else:
        return Response(status.HTTP_404_NOT_FOUND)

 

转载于:https://my.oschina.net/liuyuantao/blog/858036

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值