##language:zh #pragma section-numbers on '''Django 实践笔记--缓存 ''' ::-- ZoomQuiet [<>] <> ## 默许导航,请保留 <> {{{老生 hide details 4:06 pm (6 minutes ago) reply-to python-chinese@lists.python.cn to python-chinese@lists.python.cn date Mar 30, 2007 4:06 PM subject [python-chinese] 轻松玩转django缓存 }}} = 轻松玩转django缓存 = == 前言 == 因最近公司网站承受访问压力过大,经常导致页面报错,在研究django缓存时找了很多相关的资料,但没有见到有介绍django缓存从配置到实现再到实现机制介绍的文章,所以有了写这篇BLOG的想法,一来是可以加深自己对django缓存的理解,并作为学习笔记,二是可以给那些刚对django入门并想迫切在短时间内应用缓存功能的朋友们起到抛砖引玉的作用。 以下篇章仅做为个人笔记之用,假如你不幸看到了本文,内容仅供参考,误人子弟的罪名实在太大,笔者可担当不起。。。 == 配置cache方式及内部实现机制 == django中cache大体分为三种,即针对全站的缓存配置、针对视图的缓存配置、针对数据的缓存配置。其中针对视图及数据的配置,大体都无需在settings.py中设置,唯独全站的缓存配置必须在settings.py中进行配置,且还有一点就是进行全站及视图缓存时要区分开匿名用户和已登陆用户的显示,详见以下的CACHE_MIDDLEWARE_ANONYMOUS_ONLY讲解。 项目中的settings.py文件: {{{ MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.middleware.cache.CacheMiddleware ', 'django.middleware.common.CommonMiddleware', 'django.middleware.doc.XViewMiddleware', # 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', 'django.middleware.gzip.GZipMiddleware ', ) }}} settings.py文件中的MIDDLEWARE_CLASSES添加'django.middleware.cache.CacheMiddleware'为启用全站缓存配置,此处的中间件排序位置很重要,必须要将此CacheMiddleware放在'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware '之下,因为此处两个文件都会往request中写入相应的数据。此处针对配置全站缓存还必须指定默认的缓存时间CACHE_MIDDLEWARE_SECONDS值及CACHE_MIDDLEWARE_KEY_PREFIX值(可选)。 {{{ CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True }}} 添加以上配置,此功能是配置全站缓存时有关匿名用户和登陆了的用户视图是否从缓存中读取并显示,如果是True,即登陆用户读的数据不会从缓存中读取。此选项针对视图进行缓存配置时同样奏效。 == 实现cache的编码实现 == 针对全站缓存无需进行任何编码实现,针对试图及数据的缓存稍有区别,可能最具可观性的还算是针对数据的缓存,详见以下编码实现: === 针对数据编码实现 === {{{ from django.core.cache import cache #存储缓存数据 cache.set('cache_key',data,60*15)#cache_key为存储在缓存中的唯一值,data为存储的数据,60*15为缓存数据的时间 #获取缓存数据 cache.get('cache_key',None)#cache_key为储存缓存数据的唯一值 }}} === 针对视图编码实现 === {{{ from django.views.decorators.cache import cache_page def BaCreate(request) .... BaCreate = cache_page(BaCreate,60*9) }}} 以上代码是在处理具体应用的代码中写入,如views.py中写入,在官方站点的文挡上还有另外一种方式及在方法前加上@cache_page(60 * 15),但这种方式还没调试成功,估计还需配置什么,或者版本不对。针对试图编码实现cache还有一种方式,就在urls.py中定义,这也是推荐的方式,详细定义如下: * urls.py文件:{{{ from baindex from django.views.decorators.cache import cache_page (r'^ba/$', cache_page(baindex,1*60)), }}} 此处就定义了baindex方法所对应视图的缓存,至于为什么是做视图缓存所推荐的方式,这就留给你自己去想了。:) == 小结 == 以上就是轻松玩转django缓存实现的全过程,至于你选择那种方式,就看你自己的应用了,但我还是推荐视图+数据进行缓存,当然视图只适合那些数据变动不大的页面,不过我想那些变动不大的页面估计基本上没有,就算页面正文没有变动,页面的其它模块估计也会要有相应的变动。不过现在不是流行起了Ajax吗?可能Ajax在这里能得到很好的应用。 当然以上仅是cache的配置及实现过程,还有一点就是选择什么样的CACHE_BACKEND就不属这篇BLOG的内容了,不过要提醒下假如你用memcached的话,启动memcached记得指定IP地址,笔者就忽略了此处害得冤枉花费了一整天的时间。。 === 全站缓存及视图缓存的机制 === '''最后还是谈谈djano关于全站缓存及视图缓存的机制,对于全站缓存我们完全可以将它看成是对全部视图进行缓存的实现,''' * 这也是笔者在调试中发现的,在调试中发现某个URL被请求后所储藏到cache中的key(唯一值)都是同一个。 * 在django源文件中的utils/cache.py文件中有获取每个页面所被缓存的key为: {{{ views.decorators.cache.cache_page.lzz./showbaposts/.d41d8cd98f00b204e9800998ecf8427e }}} * 其中共分为四段,注解为: `views.decorators.cache.cache_page.(settings.py中的CACHE_MIDDLEWARE_KEY_PREFIX值).(每个请求的页面地址).(获取request中相关属性的md5编码值(调试时都为[]))` * 还有一种key为` 'views.decorators.cache.cache_header.%s.%s' % (key_prefix, request.path )`, * 猜想功能是针对upstream 缓存和Vary headers的,对于这些也不展开研究了,详见django缓存的相应文档。 * 至于视图缓存中数据的储存和获取的实现在django源文件下的views\middleware\cache.py文件中的process_request和process_response方法中。其在这里如果我们知道某个页面被缓存的key后,我们完全可以在后台写个小脚本用来实现针对某个页面的的数据来进行修改,这种应用就可以解决那些压力比较大的站点,至于怎么解决,就不展开谈了。。。 == 反馈 ==