Django如何正确缓存以重用数据?(使用django-mptt包和redis模块)

时间:2016-10-12 04:30:52

标签: python django caching

我正在制作一种动态菜单。当您单击顶部的菜单时,它会在左侧显示子菜单。我搜索了关键字'动态菜单'来自stackoverflow和谷歌。我有想法建立那种菜单。我在下面做了。

1)通过自定义上下文处理器在上下文中将数据(菜单列表)呈现给模板。

2)使用django-mptt包提供的自定义模板标记。

3)在基本模板中显示顶部菜单。

4)根据您点击的顶级菜单移动到另一个模板以显示子菜单

我使自定义context_processor在每个模板的上下文中使用菜单。

context_processor.py

from manager.models import Menu

def menu(request):
    menu_list = list(Menu.objects.all())
    return {'menu':menu_list}

template.py(例如)

{% load mptt_tags %}

<nav id="{{ menu_id }}" class="tree-menu">
    <ul>
        {% recursetree menu %}
            <li class="menu
                {% if node.is_root_node %}root{% endif %}
                {% if node.is_child_node %}child{% endif %}
                {% if node.is_leaf_node %}leaf{% endif %}

                {% if current_menu in node.get_descendants %}open{% else %}closed{% endif %}
            ">
                <a href="?{{ node.menu_name }}={{ node.pk }}">{{ node.menu_name }}</a>
                {% if not node.is_leaf_node %}
                    <ul class="children">
                        {{ children }}
                    </ul>
                {% endif %}
                {% if node.items and node.items.exists %}
                    <ul class="items">
                        {% for item in node.items.all %}
                            {% if item_template %}
                                {% include item_template %}
                            {% else %}
                                {% include "menu/tree-item.html" %}
                            {% endif %}
                        {% endfor %}
                    </ul>
                {% endif %}
            </li>
        {% endrecursetree %}
    </ul>
</nav>

mptt_tags.py

@register.tag
def recursetree(parser, token):
    """
    Iterates over the nodes in the tree, and renders the contained block for each node.
    This tag will recursively render children into the template variable {{ children }}.
    Only one database query is required (children are cached for the whole tree)

    Usage:
            <ul>
                {% recursetree nodes %}
                    <li>
                        {{ node.name }}
                        {% if not node.is_leaf_node %}
                            <ul>
                                {{ children }}
                            </ul>
                        {% endif %}
                    </li>
                {% endrecursetree %}
            </ul>
    """
    bits = token.contents.split()
    if len(bits) != 2:
        raise template.TemplateSyntaxError(_('%s tag requires a queryset') % bits[0])

    queryset_var = template.Variable(bits[1])

    template_nodes = parser.parse(('endrecursetree',))
    parser.delete_first_token()

    return RecurseTreeNode(template_nodes, queryset_var)

我的问题

  1. 如果您看到关于QuerySet的django手册,它会说&#34;每个QuerySet都包含一个缓存来最小化数据库访问&#34;。很明显,如果您在某个规则中查询相同的数据,它似乎不会再次命中数据库但返回缓存中的结果。然后我在自定义上下文处理器中查询Menu.objects.all()。这个结果(menu_list = Menu.objects.all())每次都在上下文中,你可以重复使用每个模板上的菜单数据。 是否重新使用缓存中的结果而不再次访问数据库?

  2. 如果每次模板加载此菜单列表时自定义上下文处理器命中数据库中的menu_list = Menu.objects.all(),是否以这种方式重用缓存中的菜单数据而不是每次都访问数据库

  3. context_processors.py

    from manager.models import Menu
    from django.core.cache import cache
    
    def menu(request):
    
        menu_list = cache.get_or_set('menu_list', list(Menu.objects.all()))
    
        return {'menu':menu_list, 'redis':"Food"}
    
    1. 最后,我不知道是否有很多人使用django-mptt包。我想只有少数人有亲自使用它的经验。它说&#34;只需要一个数据库查询(为整个树缓存子项)&#34; 这是否意味着如果我使用django-mptt包并从模板上获取菜单,它会自动缓存其数据?
    2. 好吧,我不清楚django缓存系统。

      如果你能给我答案和洞察我的问题,我将非常感激。谢谢你的阅读!

0 个答案:

没有答案