Darwin Tech
Darwin Tech

Reputation: 18929

Django caching in a custom context processor

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

Answers (2)

Visgean Skeloru
Visgean Skeloru

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

jpic
jpic

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

Related Questions