Django:使页面缓存无效

时间:2014-02-20 15:43:49

标签: django caching memcached

我正在尝试使用@cache_page装饰器,并使缓存无效。我想:

  • 缓存主页('索引')页面。
  • 转到新页面('non_refreshing_page'),该页面不会触及该页面。
  • 返回主页,查看页面的缓存版本。
  • 转到新页面('refresh_page'),这会使主页的缓存无效。
  • 返回主页,查看该页面的刷新版本。

这几乎可行。通过使用memcdump,我可以看到正在清除缓存。但是当我回到主页并希望看到一个刷新的页面时,我看到了一个缓存版本。我实际看到更新版本的唯一方法是回家 - > refresh_page - >主页,然后键入ctrl-R或ctrl-F5。

我是否以某种方式对抗浏览器缓存?如果是这样,我如何使浏览器缓存无效?当我注释掉缓存装饰器时,我没有遇到这个问题,所以即使这不完全是一个django问题,django中的缓存似乎导致了浏览器缓存页面。

我把我的测试项目放在github上。主页加载10个随机数,因此您可以轻松查看是否有新版本的页面或缓存版本。我认为该项目最相关的页面是views.py

我根据Expire a view-cache in Django?调整了我对失效的主要方法。

这是我的views.py:

from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.decorators.cache import cache_page

from django.utils.cache import get_cache_key
from django.core.cache import cache
from django.http import HttpRequest
from django.core.urlresolvers import reverse

from random import randint


@cache_page(60 * 10)
def index(request):
    numbers = [randint(1,9) for x in range(0,10)]

    return render_to_response('random_app/index.html',
                              {'numbers': numbers,
                               },
                              context_instance=RequestContext(request))


def refreshing_page(request):
    # Invalidated the index page.
    invalidate_cache('index')
    return render_to_response('random_app/refreshing_page.html',
                              {},
                              context_instance=RequestContext(request))


def non_refreshing_page(request):
    return render_to_response('random_app/non_refreshing_page.html',
                              {},
                              context_instance=RequestContext(request))


def invalidate_cache(view_path, args=[], namespace=None, key_prefix=None):
    """Function to allow invalidating a view-level cache.
    Adapted from: https://stackoverflow.com/questions/2268417/expire-a-view-cache-in-django
    """
    # Usage: invalidate_cache('index', namespace='ed_news', key_prefix=':1:')

    # Create a fake request.
    request = HttpRequest()
    # Get the request path.
    if namespace:
        view_path = namespace + ":" + view_path

    request.path = reverse(view_path, args=args)
    #print 'request:', request

    # Get cache key, expire if the cached item exists.
    # Using the key_prefix did not work on first testing.
    #key = get_cache_key(request, key_prefix=key_prefix)
    page_key = get_cache_key(request)
    header_key = ''

    if page_key:
        # Need to clear page and header cache. Get the header key
        #  from the page key.
        # Typical page key: :1:views.decorators.cache.cache_page..GET.6666cd76f96956469e7be39d750cc7d9.d41d8cd98f00b204e9800998ecf8427e.en-us.UTC
        # Typical header key: :1:views.decorators.cache.cache_header..6666cd76f96956469e7be39d750cc7d9.en-us.UTC
        #  Change _page..GET. to _header..
        #  then lose the second hash.
        import re
        p = re.compile("(.*)_page\.\.GET\.([a-z0-9]*)\.[a-z0-9]*(.*en-us.UTC)")
        m = p.search(page_key)
        header_key = m.groups()[0] + '_header..' + m.groups()[1] + m.groups()[2]

        print '\n\nviews.invalidate_cache'
        print 'page_key:', page_key
        print 'header_key:', header_key

        # If the page/ header have been cached, destroy them.
        if cache.get(page_key):
            # Delete the page and header caches.
            cache.delete(page_key)
            cache.delete(header_key)

            print 'invalidated cache'
            return True

    print "couldn't invalidate cache"
    return False

0 个答案:

没有答案