You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django 3.2.6二级菜单最优查询方式及模板实现咨询

最优查询方案

你当前的场景是固定两层的级联菜单,完全可以用Django ORM自带的prefetch_related特性实现最优查询,总共仅执行3次SQL,不需要写原生SQL,也不会出现N+1查询问题,性能足够满足绝大多数场景,不需要依赖模板缓存掩盖效率问题。

注意你的模型里用了动态模板生成related_name,格式为你的app名_模型名小写_related,下面代码里的占位符需要替换为你实际的对应值即可:

from django.db.models import Prefetch

# 预取二级菜单,过滤已归档数据、按rank排序
level2_prefetch = Prefetch(
    '替换为你的app名_menuleveltwo_related',
    queryset=MenuLevelTwo.objects.filter(archived=False).order_by('rank'),
    to_attr='sorted_level2'
)

# 预取一级菜单,同时关联预取二级菜单,过滤已归档数据、按rank排序
level1_prefetch = Prefetch(
    '替换为你的app名_menulevelone_related',
    queryset=MenuLevelOne.objects.filter(archived=False).order_by('rank').prefetch_related(level2_prefetch),
    to_attr='sorted_level1'
)

# 最终查询顶级菜单,仅查启用的TOP类型、过滤已归档、按rank排序
menus = Menu.objects.filter(
    archived=False,
    type=MenuTypes.TOP.value
).order_by('rank').prefetch_related(level1_prefetch)
模板实现草稿

直接嵌套循环即可渲染出双层菜单结构,示例如下:

<ul class="top-menu">
{% for top_item in menus %}
  <li>
    {{ top_item.name }}
    <ul class="level-1-menu">
    {% for level1 in top_item.sorted_level1 %}
      <li>
        {{ level1.html|safe }}
        {% if level1.sorted_level2 %}
        <ul class="level-2-menu">
        {% for level2 in level1.sorted_level2 %}
          <li>{{ level2.html|safe }}</li>
        {% endfor %}
        </ul>
        {% endif %}
      </li>
    {% endfor %}
    </ul>
  </li>
{% endfor %}
</ul>

如果菜单更新频率很低,还可以加模板片段缓存进一步优化性能:

{% load cache %}
{% cache 3600 site_main_menu %}
<!-- 上面的菜单渲染代码放这里 -->
{% endcache %}

其中3600为缓存有效期,单位为秒,可根据业务需求调整。

内容的提问来源于stack exchange,提问作者Trts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 09:30:02