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

Django菜单实现求助:输出菜单列表及匹配ID的子菜单

Django 层级菜单实现步骤

1. 定义菜单模型

在你的app下的models.py里创建菜单模型,通过自关联外键实现父子菜单的层级关系:

from django.db import models

class Menu(models.Model):
    name = models.CharField(max_length=50, verbose_name="菜单名称")
    # 父菜单关联自身,null/blank允许该菜单为顶级菜单
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='submenus', verbose_name="父菜单")
    menu_id = models.CharField(max_length=50, unique=True, verbose_name="匹配用ID")  # 对应你需要的'catr'

    def __str__(self):
        return self.name

写完模型后执行迁移命令:

python manage.py makemigrations
python manage.py migrate

然后到Django后台添加数据:先创建顶级菜单name='catr'、menu_id='catr';再创建子菜单name='subcat',父菜单选择刚才的catr即可。

2. 编写视图逻辑

在views.py中查询菜单数据,并获取当前需要匹配的菜单ID(以下提供两种常见获取方式):

from django.shortcuts import render
from .models import Menu

# 方式1:从URL路径参数获取匹配ID
def menu_view(request, menu_id=''):
    # 预加载子菜单,减少数据库查询次数
    parent_menus = Menu.objects.filter(parent__isnull=True).prefetch_related('submenus')
    return render(request, 'menu.html', {
        'parent_menus': parent_menus,
        'current_menu_id': menu_id
    })

# 方式2:从GET参数获取匹配ID(比如访问时带?menu_id=catr)
# def menu_view(request):
#     current_menu_id = request.GET.get('menu_id', '')
#     parent_menus = Menu.objects.filter(parent__isnull=True).prefetch_related('submenus')
#     return render(request, 'menu.html', {'parent_menus': parent_menus, 'current_menu_id': current_menu_id})

如果用路径参数的方式,需要在urls.py中配置路由:

from django.urls import path
from . import views

urlpatterns = [
    path('menu/<str:menu_id>/', views.menu_view, name='menu'),
    # 可选:添加默认路径,不带参数时展示所有顶级菜单
    path('menu/', views.menu_view, name='menu_default'),
]

3. 模板渲染菜单

在模板文件menu.html中循环渲染菜单,当菜单ID与当前匹配ID一致时,展开对应的子菜单:

<ul class="menu-list">
    {% for parent in parent_menus %}
        <li class="menu-item">
            {{ parent.name }}
            <!-- 匹配到目标菜单ID且存在子菜单时,展开子菜单 -->
            {% if parent.menu_id == current_menu_id and parent.submenus.exists %}
                <ul class="submenu-list">
                    {% for sub in parent.submenus.all %}
                        <li class="submenu-item">{{ sub.name }}</li>
                    {% endfor %}
                </ul>
            {% endif %}
        </li>
    {% endfor %}
</ul>

测试验证

启动Django服务后,访问http://localhost:8000/menu/catr/,就能看到catr菜单下展开subcat子菜单;访问http://localhost:8000/menu/则只显示所有顶级菜单。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:55:15