Django:当缓存密钥使用GET参数时,如何删除模板缓存?

时间:2013-03-25 13:00:56

标签: django caching django-templates django-cache

这个问题一直困扰着我:

  • 我有一些观点接受GET参数来修改查询集(order_by和pagination)并缓存它。
  • 这些视图非常相似,它们都共享相同的模板。
  • 这些模板缓存了页面的一部分(考虑了GET参数),如下所示:

    {% with order=request.GET.order_by %}{% with page=request.GET.page %}{# I need them to set the cache name #}
    {% cache 7200 template urlname order page %}
    .... some part of the page...
    {% endcache %}
    {% endwith %}{% endwith %}{# with order and with page #}
    
  • 删除查询集缓存是小菜一碟,但删除模板缓存已经证明非常复杂。您通常需要生成cache_key,like explained in the DOCS。我的问题是我必须生成所有可能的密钥组合并删除它们,我这样做:

    SITE_LIST_OPTIONS = [
        ('url', [reverse_lazy('site_list'),
                 reverse_lazy('best_site_list'),
                 reverse_lazy('banned_site_list'),
                 reverse_lazy('toreview_site_list')]),
        ('order', ['url', 'country', 'upstream_rank']),
        ('page', range(10))]
    
    
    def delete_cache_keys(keys):
        '''Deletes all the cache keys on the provided list.'''
        for e in keys:
            cache.delete(e)
    
    
    def delete_template_cache(key, filters=None):
        # first, we need to get all possible filter combination options
        if filters:
            options = combine_options(filters)
            keys = [make_template_fragment_key(key, ops) for ops in options]
            delete_cache_keys(keys)
        else:
            key = make_template_fragment_key(key, filters)
            cache.delete(key)
    
    # context_processor.py (used to generate key in template)
    
    def urlname(request):
        return {'urlname': resolve_urlname(request)}
    

我想我不是第一个尝试基于GET参数缓存模板的人,所以......有没有更好的方法来删除与这个特定模板相关的所有缓存?

编辑:不确定为什么格式化没有显示但是这里是一个更清洁的版本以防http://dpaste.org/XYYo2/

1 个答案:

答案 0 :(得分:0)

您可以将模板的所有缓存片段组合在一起,为它们提供绑定到模板的组缓存键。如果要使与模板相关的所有内容无效,只需清除模板的组密钥:

>>> from django.core.cache import cache

>>> template_name = 'foo.html'
>>> cache.set(template_name, 1)
>>> make_group_key = lambda: '{name}-{version}'.format(
        name=template_name, version=cache.get(template_name))
>>> cache.set(make_group_key(), 'page content...')
>>> cache.get(make_group_key())
'page content...'

>>> cache.incr(template_name)
>>> cache.get(make_group_key()) is None
True

对于您的代码,您可以编写一个模板标记,将组密钥传播到上下文,例如

{% get_template_key template as tmpl_key %}
{% cache 7200 template urlname order page tmpl_key %}

或者你可以在视图或其他地方生成密钥。

删除部分就像cache.incr(template_name)一样简单(您可能需要处理模板名称不再存在的异常)

此方法添加额外的缓存往返,但通常足够快。