Django使用redis进行缓存

对于非经常更新的服务器数据,若每次都从硬盘读取一次,会浪费服务器资源、拖慢响应速度,而且数据更新频率较高,服务器负担比较大。若保存到数据库,还需要额外建立一张对应的表存储数据。一个更好的方法是在Django中使用Redis进行缓存。

缓存配置

首先安装django-redis:

pip install django-redis

在setting文件中设置CACHES:

CACHES = {
    'default':{
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION':"redis://you_host:you_port/1",
        'TIMEOUT': 200,   # NONE 永不超时
        'OPTIONS':{
                "PASSWORD":"you_passwd",#密码,没有可不设置
                'CLIENT_CLASS': 'django_redis.client.DefaultClient', #redis-py 客户端
                'PICKLE_VERSION': -1, # 插件使用PICKLE进行序列化,-1表示最新版本
                'CONNECTION_POOL_KWARGS': {"max_connections": 100}, # 连接池最大连接数
                'SOCKET_CONNECT_TIMEOUT': 5,    # 连接超时
                'SOCKET_TIMEOUT': 5,    # 读写超时
                }
        #"KEY_PREFIX ":"test",#前缀
    }
}

配置好后运行程序,进行测试:
引入库

>>>from django.core.cache import cache
>>>cache.set("test","abscd",30)
True

同时查看redis-cli客户端是否写入:
在这里插入图片描述
已经写入redis,说明配置没问题。

缓存

1.视图缓存

缓存框架通用的方法就是缓存视图函数,在需要进行缓存的视图函数文件中引入django.views.decorators.cache定义的装饰器cache_page,它可以自动缓存视图:

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

在上面的例子里,cache_page 使用了一个参数:缓存过期时间,以秒为单位。my_view() 视图的结果将缓存15分钟。(注意,用 60 * 15 这样的方式编写,目的是方便阅读, 也就是15分钟),查看一下cache_page函数的定义:

def cache_page(timeout, *, cache=None, key_prefix=None):
    """
    timeout:为上面设置的超时时间;
    cache:可以指定使用哪个缓存;
    key_prefix:缓存键值的前缀,如果setting里设置了KEY_PREFIX,它的键值将与KEY_PREFIX连接起来redis里缓存

可以这样使用,指定超时时间、指定使用哪个缓存、指定键名前缀

@cache_page(60 * 15, cache="special_cache",key_prefix="site1")
def my_view(request):
    ...
2.在 URLconf 中指定视图缓存

视图缓存还可以在url上进行。打开urls.py文件,引入相应的库,将需要缓存的url视图用cache_page包裹:

from django.views.decorators.cache import cache_page

urlpatterns = [
 path('foo//', cache_page(60 * 15)(my_view)),#缓存将保留15分钟
]

这样如果url (比如 /foo/23/ )已经被请求,那么随后的请求都将使用缓存,每个url都将被单独缓存。

3.在模板中进行缓存

在模板文件中使用缓存需要在顶部先引入 {% load cache %} ,然后就可以使用 {% cache %} 标签进行缓存操作,使用缓存标签至少需要提供两个参数,一个是超时时间、一个是键名,如:

{% load cache %}
{% cache 500 sidebar %}#500为缓存时间,sidebar为缓存片段名称
    .. sidebar ..
{% endcache %}

如果想为每个登录用户单独缓存的话,可以这样:

{% load cache %}
{% cache 500 sidebar request.user.username %} #增加了用户这个参数,通常网站缓存还是得以用户为基准
    .. sidebar for logged in user ..
{% endcache %}

注意:这里的缓存失效时间500可以为一个模板变量 ,{% cache my_var sidebar %} 可以从后端传递过来。

底层API

刚才介绍的都是基于页面的缓存,有时候我们并不想把页面所有内容都缓存,有些可变内容也不适合缓存,对于这些情况django提供了一些缓存api用于更细粒度的缓存,在django文档中所说,可以被pickle的python对象都可以缓存,这就包括:模型对象的字符串、字典、列表,大部分python对象都可以被pickle。

1.访问缓存

django.core.cache.caches
对caches的操作基本与对字典操作一样。

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

但是当我们访问一个不存在的键的时候,将会抛出InvalidCacheBackendError 错误。这时我们可以使用:

from django.core.cache import cache
2.基本用法

cache.set(key, value, timeout=DEFAULT_TIMEOUT, version=None)

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

cache.get(key, default=None, version=None)


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

key 是一个字符串,value 可以pickle 的Python 对象。

timeout 参数是可选的,默认为 CACHES 中相应后端的 timeout 参数。timeout 设置为 None 时将永久缓存,timeout 为0将不缓存值。

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

建议不要在缓存中存储为 None 的值,因为你不能分辨是你存储的 None 值还是因为缓存命中返回的 None 值。

cache.add(key, value, timeout=DEFAULT_TIMEOUT, version=None)
在键不存在的时候,使用 add() 方法可以添加键。它与 set() 带有相同的参数,但如果指定的键已经存在,将不会尝试更新缓存。

>>> cache.set('add_key', 'Initial value')
>>> cache.add('add_key', 'New value')
>>> cache.get('add_key') 
'Initial value'
#cache.get("add_key"," new_value"),get方法还可以像字典一样没有得到值的话返回一个默认值“new_value”

cache.get_or_set(key, default, timeout=DEFAULT_TIMEOUT, version=None)
如果你想得到键值或者如果键不在缓存中时设置一个值,可以使用 get_or_set() 方法。

>>> cache.get('my_new_key')  # returns None
>>> cache.get_or_set('my_new_key', 'my new value', 100)
'my new value'

cache.get_many(keys, version=None)
cache.set_many(dict, timeout)

看示例:

>>> cache.set('a', 1)
>>> cache.set('b', 2)
>>> cache.set('c', 3)
>>> cache.get_many(['a', 'b', 'c'])#列表作为参数
{'a': 1, 'b': 2, 'c': 3}

>>> cache.set_many({'a': 1, 'b': 2, 'c': 3})#字典作为参数
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}

cache.delete(key, version=None)
cache.delete_many(keys, version=None)

>>> cache.delete('a') #删除一个键
>>>> cache.delete_many(['a', 'b', 'c'])#一次性删除多个

cache.incr(key, delta=1, version=None)
cache.decr(key, delta=1, version=None)

使用 incr() 或 decr() 方法来递增或递减一个已经存在的键的值,递增或递减一个不存在的缓存键,将会引发 ValueError 错误。

>>> cache.set('num', 1)
>>> cache.incr('num')
2
>>> cache.incr('num', 10)
12
>>> cache.decr('num')
11
>>> cache.decr('num', 5)
6

cache.touch(key, timeout=DEFAULT_TIMEOUT, version=None)
cache.touch() 为键设置一个新的过期时间。比如,更新一个键,过期时间为10秒钟

>>> cache.touch('a', 10)
True

使用 Vary 头

默认情况下我们的对 (http://www.happyhong.cn/)这个链接的缓存对于所有访问者都是一样的,不能针对不同用户代理进行区别缓存,如果想使用基于cookies、user-agent的不同进行缓存,就需要使用django提供的 django.views.decorators.vary.vary_on_headers() 视图装饰器,像这样:

from django.views.decorators.vary import vary_on_headers
@vary_on_headers('User-Agent')
def my_view(request):
    ...

Django 自带的缓存中间件将为每一个用户代理即user-agent缓存一个独立的页面版本,传递给 vary_on_headers 的头是不区分大小写的;“User-Agent” 和 “user-agent” 是一样的
可以传递多个头参数给 vary_on_headers():

@vary_on_headers('User-Agent', 'Cookie')
def my_view(request):
   ...

这就意味着要根据每个用户代理和 cookie 的组合来获取它自己的缓存值。

使用其它头控制缓存

from django.views.decorators.cache import cache_control

@cache_control(private=True)
def my_view(request):

关于cache_control后续再更新吧,更多爬虫、django相关、软件安装请移步从今天开始种树。。。

你可能感兴趣的:(django学习,python,django,python,redis)