浅谈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 相关文章推荐
Python读取mp3中ID3信息的方法
Mar 05 Python
python判断windows系统是32位还是64位的方法
May 11 Python
Python控制多进程与多线程并发数总结
Oct 26 Python
Python调用系统底层API播放wav文件的方法
Aug 11 Python
浅析python参数的知识点
Dec 10 Python
Python之pymysql的使用小结
Jul 01 Python
Django框架中序列化和反序列化的例子
Aug 06 Python
浅谈python之自动化运维(Paramiko)
Jan 31 Python
屏蔽Django admin界面添加按钮的操作
Mar 11 Python
Python unittest单元测试框架及断言方法
Apr 15 Python
python中spy++的使用超详细教程
Jan 29 Python
Python实现排序方法常见的四种
Jul 15 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
php的POSIX 函数以及进程测试的深入分析
2013/06/03 PHP
php如何比较两个浮点数是否相等详解
2019/02/12 PHP
THINKPHP5.1 Config的配置与获取详解
2020/06/08 PHP
一段利用WSH获取登录时间的jscript代码
2008/05/11 Javascript
JavaScript 以对象为索引的关联数组
2010/05/19 Javascript
基于jquery的关于动态创建DOM元素的问题
2010/12/24 Javascript
原生JS实现表单checkbook获取已选择的值
2013/07/21 Javascript
jquery ajax实现下拉框三级无刷新联动,且保存保持选中值状态
2013/10/29 Javascript
Js获取下拉框选定项的值和文本的实现代码
2014/02/26 Javascript
JavaScript返回当前会话cookie全部键值对照的方法
2015/04/03 Javascript
简介JavaScript中的italics()方法的使用
2015/06/08 Javascript
快速学习jQuery插件 jquery.validate.js表单验证插件使用方法
2015/12/01 Javascript
js实现按钮控制带有停顿效果的图片滚动
2016/08/30 Javascript
vue指令以及dom操作详解
2017/03/04 Javascript
js学习总结之dom2级事件基础知识详解
2017/07/27 Javascript
浅谈Angular 中何时取消订阅
2017/11/22 Javascript
js装饰设计模式学习心得
2018/02/17 Javascript
vue中移动端调取本地的复制的文本方式
2020/07/18 Javascript
解决vue单页面应用打包后相对路径、绝对路径相关问题
2020/08/14 Javascript
[03:09]DOTA2亚洲邀请赛 LGD战队出场宣传片
2015/02/07 DOTA
python开启摄像头以及深度学习实现目标检测方法
2018/08/03 Python
django 捕获异常和日志系统过程详解
2019/07/18 Python
tensorflow获取预训练模型某层参数并赋值到当前网络指定层方式
2020/01/24 Python
Python如何执行精确的浮点数运算
2020/07/31 Python
HTML5拖放功能_动力节点Java学院整理
2017/07/13 HTML / CSS
Html5基于canvas实现电子签名并生成PDF文档
2020/12/07 HTML / CSS
澳洲CFL商城:CHEMIST FOR LESS(中文)
2021/02/28 全球购物
百度JavaScript笔试题
2015/01/15 面试题
营销主管自我评价怎么写
2013/09/19 职场文书
网络优化专员求职信
2014/05/04 职场文书
检察机关个人对照检查材料
2014/09/15 职场文书
2014年全国爱牙日宣传活动方案
2014/09/21 职场文书
群众路线四风问题整改措施
2014/09/27 职场文书
庭外和解协议书
2016/03/23 职场文书
Python Parser的用法
2021/05/12 Python
MySQL系列之三 基础篇
2021/07/02 MySQL