我认为在这里一个好的做法是创建一个模板标签来完成这个工作。这样你就可以缓存渲染后的模板,并且只在第一次渲染时访问数据库。
首先,在你的应用程序中创建模板标签。
templatetags/show_categories_list.py
from django.core.cache import cache
@register.simple_tag
def show_categories_list():
cached = cache.get('CATEGORIES_LIST_CACHE_KEY', None)
if cached is None:
categories = Category.objects.all()
rendered = render_to_string('all_categories.html', {'categories': categories})
cache.set('CATEGORIES_LIST_CACHE_KEY', rendered)
return rendered
return cached
然后,创建要使用的模板。
all_categories.html
{% for category in categories %}
<h1>{{ category.name }}</h1>
<ul>
{% for sub in category.subcategory_set.all %}
<li>{{ sub.name }}</li>
{% endfor %}
</ul>
{% endfor %}
在您的模型中覆盖保存方法,以便删除类别列表缓存条目(强制在下一次请求时呈现,这也可以放置在(pre|post)_save信号处):
models.py
class Category(models.Model):
name = models.CharField(max_length=50)
def save(self, *args, **kwargs):
cache.delete('CATEGORIES_LIST_CACHE_KEY')
return super(Category, self).save(*args, **kwargs)
class SubCatergory(models.Model):
parent_category = models.ForeignKey(Category)
name = models.CharField(max_length=100)
def save(self, *args, **kwargs):
cache.delete('CATEGORIES_LIST_CACHE_KEY')
return super(Category, self).save(*args, **kwargs)
最后,像这样使用它:
base.html
{% load show_categories_list %}
{% show_categories_list %}
您还可以为缓存条目添加超时时间,这样就不必在模型中覆盖保存方法,但是您需要等待超时时间才能再次渲染它。
一些有用的参考:
http://docs.djangoproject.com/en/1.2/howto/custom-template-tags/#shortcut-for-simple-tags
http://docs.djangoproject.com/en/1.2/topics/cache/#the-low-level-cache-api
http://docs.djangoproject.com/en/1.2/topics/signals/