浅谈Django的缓存机制


Posted in Python onAugust 23, 2018

由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。

Django中提供了6种缓存方式:

  1. 开发调试
  2. 内存
  3. 文件
  4. 数据库
  5. Memcache缓存(python-memcached模块)
  6. Memcache缓存(pylibmc模块)

通用配置

'TIMEOUT': 300,            # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
    'OPTIONS':{
     'MAX_ENTRIES': 300,          # 最大缓存个数(默认300)
     'CULL_FREQUENCY': 3,          # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
    },
    'KEY_PREFIX': '',            # 缓存key的前缀(默认空)
    'VERSION': 1,             # 缓存key的版本(默认1)
    'KEY_FUNCTION' 函数名           # 生成key的函数(默认函数会生成为:【前缀:版本:key】)

以上六中模式都可以使用

自定义key

def default_key_func(key, key_prefix, version):
  """
  Default function to generate keys.

  Constructs the key used by all other methods. By default it prepends
  the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
  function with custom key making behavior.
  """
  return '%s:%s:%s' % (key_prefix, version, key)

 def get_key_func(key_func):
  """
  Function to decide which key function to use.

  Defaults to ``default_key_func``.
  """
  if key_func is not None:
   if callable(key_func):
    return key_func
   else:
    return import_string(key_func)
  return default_key_func

开发调试

# 此为开始调试用,实际内部不做任何操作
  # 配置:
    CACHES = {
      'default': {
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',   # 引擎
       通用配置
      }
    }

内存

# 此缓存将内容保存至内存的变量中
  # 配置:
    CACHES = {
      'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
       通用配置
      }
    }

  # 注:其他配置同开发调试版本

文件

# 此缓存将内容保存至文件
  # 配置:

    CACHES = {
      'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/var/tmp/django_cache',
         通用配置
      }
    }
  # 注:其他配置同开发调试版本

数据库

# 此缓存将内容保存至数据库

  # 配置:
    CACHES = {
      'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'my_cache_table', # 数据库表
       通用配置
      }
    }

  # 注:执行创建表命令 python manage.py createcachetable

Memcache缓存(python-memcached模块)

# 此缓存使用python-memcached模块连接memcache

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

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

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

Memcache缓存(pylibmc模块)

# 此缓存使用pylibmc模块连接memcache
  
  CACHES = {
    'default': {
      'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
      'LOCATION': '127.0.0.1:11211',
    }
  }

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

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

缓存的应用

单独视图缓存

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)
def my_view(request):
      ...

即通过装饰器的方式实现,导入模块之后,在需要缓存的函数前加@cache_page(60 * 15) 60*15表示缓存时间是15分钟

例子如下:

from django.views.decorators.cache import cache_page
@cache_page(10)
def cache(request):
  import time
  ctime = time.time()
  return render(request,"cache.html",{"ctime":ctime})

前端页面如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <h1>{{ ctime }}</h1>
  <h1>{{ ctime }}</h1>
  <h1>{{ ctime }}</h1>

</body>
</html>

这样在前端页面在获取的ctime的时候就会被缓存10秒钟,10秒钟之后才会变化,但是这样的话就相当月所有的调用ctime的地方都被缓存了

局部缓存

引入TemplateTag

{% load cache %}

使用缓存

{% cache 5000 缓存key %}

缓存内容

{% endcache %}

更改前端代码如下:

{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <h1>{{ ctime }}</h1>
  <h1>{{ ctime }}</h1>
  {% cache 10 c1 %}
  <h1>{{ ctime }}</h1>
  {% endcache %}
</body>
</html>

这样就实现了最后一个ctime缓存,其他两个不缓存

全站缓存

全站缓存的时候,需要在中间件的最上面添加:

'django.middleware.cache.UpdateCacheMiddleware',

在中间件的最下面添加:

'django.middleware.cache.FetchFromCacheMiddleware',

其中'django.middleware.cache.UpdateCacheMiddleware'里面只有process_response方法,在'django.middleware.cache.FetchFromCacheMiddleware'中只有process_request方法,所以最开始是直接跳过UpdateCacheMiddleware,然后从第一个到最后一个中间件的resquest,第一次没有缓存座椅匹配urls路由关系依次进过中间件的process_view,到达views函数,再经过process_exception最后经过response,到达FetchFromCacheMiddleware

另一个让我烦恼一个多小时的问题是,设置 TIMEOUT 参数无效。查找Django的源文件( ./core/cache/backends/memcached.py ),打印出设置缓存时的信息。发现不论参数设置多少,缓存的有效期都变成了600s。

后来终于在django的 conf/global_settings.py 这个文件里找到 CACHE_MIDDLEWARE_SECONDS = 600 这个参数。看名字是中间件的缓存时间,懒得深究了。在 settings.py 文件中把这个参数值也修改一下,再次测试,终于得到预期的效果。这个问题竟然在放狗都没搜到,值得一记。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
c++生成dll使用python调用dll的方法
Jan 20 Python
使用Python构建Hopfield网络的教程
Apr 14 Python
python获取一组数据里最大值max函数用法实例
May 26 Python
Python数据类型详解(一)字符串
May 08 Python
浅谈django开发者模式中的autoreload是如何实现的
Aug 18 Python
python输入错误密码用户锁定实现方法
Nov 27 Python
Python3 实现随机生成一组不重复数并按行写入文件
Apr 09 Python
python实现随机调用一个浏览器打开网页
Apr 21 Python
强悍的Python读取大文件的解决方案
Feb 16 Python
python做接口测试的必要性
Nov 20 Python
利用python制作拼图小游戏的全过程
Dec 04 Python
查找适用于matplotlib的中文字体名称与实际文件名对应关系的方法
Jan 05 Python
如何在python字符串中输入纯粹的{}
Aug 22 #Python
关于python列表增加元素的三种操作方法
Aug 22 #Python
Python Learning 列表的更多操作及示例代码
Aug 22 #Python
Python绘制的二项分布概率图示例
Aug 22 #Python
使用Python写一个量化股票提醒系统
Aug 22 #Python
Python使用numpy产生正态分布随机数的向量或矩阵操作示例
Aug 22 #Python
用Python将mysql数据导出成json的方法
Aug 21 #Python
You might like
虹吸壶煮咖啡26个注意事项
2021/03/03 冲泡冲煮
WordPress主题中添加文章列表页页码导航的PHP代码实例
2015/12/22 PHP
(function(){})()的用法与优点
2007/03/11 Javascript
用js实现控制内容的向上向下滚动效果
2007/06/26 Javascript
Ext JS 4官方文档之三 -- 类体系概述与实践
2012/12/16 Javascript
文本域中换行符的替换示例
2014/03/04 Javascript
基于jQuery实现搜索关键字自动匹配功能
2020/03/26 Javascript
详解Bootstrap四种图片样式
2016/01/04 Javascript
JavaScript中的原型继承基础学习教程
2016/05/06 Javascript
微信小程序进行微信支付的步骤昂述
2016/12/01 Javascript
javascript设计模式之策略模式学习笔记
2017/02/15 Javascript
jQuery插件HighCharts绘制2D带Label的折线图效果示例【附demo源码下载】
2017/03/08 Javascript
jQuery实现按比例缩放图片的方法
2017/04/29 jQuery
AngularJS实现的select二级联动下拉菜单功能示例
2017/10/25 Javascript
JS+CSS实现滚动数字时钟效果
2017/12/25 Javascript
手把手教你vue-cli单页到多页应用的方法
2018/05/31 Javascript
JS实现随机生成10个手机号的方法示例
2018/12/07 Javascript
解决vue单页面 回退页面 keeplive 缓存问题
2020/07/22 Javascript
详解vue 组件注册
2020/11/20 Vue.js
[45:59]EG vs OG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python Web开发模板引擎优缺点总结
2014/05/06 Python
浅析Python中的多条件排序实现
2016/06/07 Python
windows下python安装小白入门教程
2018/09/18 Python
python得到qq句柄,并显示在前台的方法
2018/10/14 Python
Python 解决OPEN读文件报错 ,路径以及r的问题
2019/12/19 Python
css3实现冲击波效果的示例代码
2018/01/11 HTML / CSS
生产车间主任的个人自我鉴定
2013/10/25 职场文书
音乐系毕业生自荐信
2013/10/27 职场文书
工商管理系学生的自我评价分享
2013/11/29 职场文书
员工拓展培训方案
2014/02/15 职场文书
应届生求职自荐信范文
2014/04/07 职场文书
安全生产工作汇报
2014/10/28 职场文书
设立有限责任公司出资协议书
2014/11/01 职场文书
平遥古城导游词
2015/02/03 职场文书
2016年幼儿园教师政治学习心得体会
2016/01/23 职场文书
2019年自助餐厅创业计划书模板
2019/08/22 职场文书