加入收藏 | 设为首页 | 会员中心 | 我要投稿 银川站长网 (https://www.0951zz.com/)- 云通信、基础存储、云上网络、机器学习、视觉智能!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

Django中的缓存机制及其达成方法

发布时间:2023-05-19 12:59:17 所属栏目:语言 来源:
导读:在本教程的《Django Cache缓存系统》一节中,我们对 Django 缓存系统做了基本的介绍,那么它在 Django 中是如何进行应用呢,在本节将对 Django 的缓存系统展开详细的描述,从它的缓存机制、使用场景以及如何进行配置

在本教程的《Django Cache缓存系统》一节中,我们对 Django 缓存系统做了基本的介绍,那么它在 Django 中是如何进行应用呢,在本节将对 Django 的缓存系统展开详细的描述,从它的缓存机制、使用场景以及如何进行配置,在本节中你将认识到什么是强缓存、什么是协商缓存,最后我们通过实际举例对缓存的使用进行说明,下面我们就正式开始本节的内容。

1. 缓存机制的分类

我们已经了解了 Django 为什么使用缓存的原因,即避免服务器通对高频率的同样请求,反复的进行计算并去数据库获取相应的数据,这样容易导致服务器过载,并浪费服务器资源。Django 的缓存很好的节解决了这一问题。

1) MemCache缓存实现流程

缓存将一个某个 views 视图函数的返回值保存至内存或者 memcached 中,若在时间约定范围内该用户又对此视图发起了请求,则不再去执行 views 中的操作,而是直接从内存或者 Redis 中获取之前已经缓存的数据,并将其返回给浏览器,这也是动态网站使用缓存的常用流程。

这里须需要大家注意,Memcached 不是 Django 自带的模块,而是需要你自己安装、配置和启动服务;Memcached 安装后,用 Python 操作 Memcached 的依赖库,最常用的是 python-memcached 和 pylibmc。但是现在也多了另外一种选择也就是 Redis,它是基于内存的缓存型数据库,同时支持数据序列化相比而言更加安全,我们推荐使用。

Redis 的工作流程总结如下:先检查客户端的请求数据是否在 Redis 中,如有,直接把请求数据返回,不再对数据库进行任何操作;如果请求的数据不在 Redis 中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到 Redis 中;每次更新数据库的同时更新 Redis 中的数据,保证与数据库的一致性。

2) Django中的缓存机制

Django 中提供多种缓存机制,如需使用需要在 settings.py 文件中进行配置,Django 提供了六种常用的缓存机制,如下所示:

开发调试缓存

本地内存缓存

数据库缓存

文件缓存

Memcache缓存(使用python-memcached模块)

Memcache缓存(使用pylibmc模块)

在这里我们对几种缓存机制进行介绍,分别是数据库缓存、文件缓存、本地内存缓存,下面我们介绍它们在 settings.py 文件中是如何进行配置的,数据库缓存的配置如下所示:

#数据缓存机制

CACHES = {

'default': {

'BACKEND':'django.core.cache.backends.db.DatabaseCache', #数据库引擎

'TIMEOUT':300, #缓存超时时间(默认300秒,None表示永不过期,0表示立即过期)

'LOCATION': 'my_cache_table',

'MAX_ENTRIES': 3, # 当前最大缓存数

'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即 1/CULL_FREQUENCY(默认3)

}

}

这里还有最红要的一步操作就是创建缓存数据表,使用如下命令:

python manage.py createcachetable my_cache_table

基于本教程中使用数据库进行缓存其实是非常鸡肋的,因为我们之所以使用缓存就是为了减少数据库的查询,但是企业环境下的数据库如果非常高速、高效,那么你可以使用这种机制,我们在这里简单讲解一下它的基本配置。大家注意各种缓存机制在 settings.py 文件的配置都是相差无几的。文件系统缓存的配置如下所示:

#基于window

CACHES = {

'default': {

'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',

'LOCATION': 'c:/foo/bar', #若是 Linux 路径写为 /home/cnet/cachetest

}

}

文件缓存机制,也是 Django 为我们提供的一种执行缓存的方法,不过这种方法相较数据库而言更慢,不过有总比没有强,在你无路可走的时候,为了实现达到缓存的目的也可以使用。

 

下面我们介绍最后一种也就是基于本地内存的缓存机制,大家知道内存的交互读写速度非常之快,所以内存资源也相当的珍贵,使用这种缓存机制也再合适不过了。

# 此缓存将内容保存至内存的变量中

CACHES = {

'default':{

'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',

'LOCATION': 'unique-snowflake',#给缓存放置的内存区设置一个名字

}

}

2. Django中使用缓存的方式

在 Django 中我们可以使用如下方式直接对缓存进行应用,前两者是通过装饰器实现的,最后一个是通过模板标签实现的:

在视图View中使用

在路由URL中使用

在模板中使用

它们的使用方式分别如下所示:

from django.views.decorators.cache import cache_page

@cache_page(60*30)#以秒为单位

def my_view(request):

...

在 django.views.decorators.cache 定义了一个自动缓存视图响应结果的装饰器 cache_page,这个装饰器接受一个参数:timeout 以秒为单位。在上例中,my_view() 视图的结果将被缓存 30 分钟,也可以写为 60*30。在路由中使用缓存的格式如下:

from django.views.decorators.cache import cache_page

urlpatterns = [

path('foo/', cache_page(60)(my_view)),

]

在模板中也可以使用缓存,也叫模板碎片缓存,如下所示:

{% load cache %}

{% cache 500 bar request.user.username %}

.. bar for logged in user ..

{% endcache %}

我们要在模版的顶部位置添加 {% load cache %},同样它也需要 {% endcache %} 结尾。模板标签 {% cache %} 将在设定的时间内,缓存标签块中包含的内容。它最少需要两个参数:依次为缓存时间(以秒为单位)以及要被缓存的片段起的名称(bar)。

3. Django缓存的实例应用

1) 视图函数中使用装饰器

通过上面的讲解我们对 Django 缓存机制与实现方法有了深入的了解,下面我们通过简单的例子进行测试,看看它是如何进行应用的。我们通过获取当前时间戳,来证明缓存机制的存在作用。

#在缓存有效时间内不会阻塞,直到缓存过期重新阻塞3秒

@cache_page(60) #缓存有效时间60s

def test_cache(request):

t1=time.time() #得到当前时间戳

time.sleep(3) #阻塞三秒

html='t1 is %s'%(t1)

return HttpResponse(html)

配置好路由映射关系,然后访问 127.0.0.1:8000/index/test_cache ,发现第一次请求时会阻塞三秒,然后再缓存期间请求页面则不需要阻塞,直到缓存过期重新阻塞。

我们可以通过谷歌浏览器 F12 查看它的响应头,其中的 Cache-Control: max-age=60 代表了最大的过期时间为 60s,它是 HTTP1.1 的产物,而另外一个 Expires 同样代表过期时间,只不过它属于 HTTP1.0 时代,可以把前者看做是后者的补充。

2) 在path中使用cache_page()

同样我们也可以在 url 中使用缓存的装饰器,方法如下所示:

from django.views.decorators.cache import cache_page

path('test_cache/',cache_page(15)(views.test_cache))

使用这种范式的时候,记得要把视图函数中的装饰器取消。

3) 实现模板中碎片化缓存

编写如下视图函数以及 test_cache.html 页面,如下所示:

#视图函数

def test_time(request):

if request.method=='GET':

return render(request,'index/test_cache.html')

elif request.method=='POST':

t1 = time.time() # 得到当前时间戳

time.sleep(3) # 阻塞三秒

return render(request,'index/test_cache.html',locals())

test_cache.html 模板页面如下所示:

<form action="/index/test_time/" method="post">

{% csrf_token %}

{% load cache %}

{% cache 30 test %}

<p>我是缓存的 {{ t1 }}</p>

{% endcache %}

<h4>

我是没有缓存的{{ t1 }}

</h4>

<input type="submit" value="提交">

</form>

配置好路由后,访问 127.0.0.1:8000/index/test_time,点击提交按钮后,你会发现有缓存的 t1 时间戳只有在 30s 以后才会改变,因为在这 30s 内它读取的都是已缓存模板片段内容。

(编辑:银川站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!