简体   繁体   中英

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.

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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM