Reputation: 18929
I have a custom context processor which I use to generate a dynamic menu and a list of current apps, site-wide:
from portal.models import *
def base_items(request):
return {
...
'app_items': App.objects.filter(isonline=True),
'menu_items': MainMenu.objects.all().order_by('position'),
}
EDIT:
My template (note that many of these urls are outside of the Django framework and vary depending on language. Hence the need to hardcode them into the db fields:
<ul class="menu">
{% for item in menu_items %}
{% if LANGUAGE_CODE = "en-us" %}
<li><a title="{{ item.title_en }}" href="{{ item.url_en }}">{{ item.title_en }}</a>
<ul>
{% for subitem in item.submenu_set.all %}
<li><a title="{{ subitem.title_en }}" href="{{ subitem.url_en }}">{{ subitem.title_en }}</a></li>
{% endfor %}
</ul>
</li>
{% else %}
<li><a title="{{ item.title_es }}" href="{{ item.url_es }}">{{ item.title_es }}</a>
<ul>
{% for subitem in item.submenu_set.all %}
<li><a title="{{ subitem.title_es }}" href="{{ subitem.url_es }}">{{ subitem.title_es }}</a></li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</ul>
My question is - how can I cache these results, which don't change very frequently?
I have tried the @cache_page decorator but I can see my pages still accessing the db for the menu items objects.
Any help much appreciated.
Upvotes: 0
Views: 2824
Reputation: 2263
Try to return lamdas expressions to your templates:
'app_items': lambda: App.objects.filter(isonline=True),
that way it does not get compiled/cached and works dynamically.
Upvotes: 1
Reputation: 33420
You can use django low level cache API. Note that you might have to cast the querysets to list.
Or, you could cache the template fragment that uses these querysets, because querysets are lazy.
Upvotes: 3