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

如何在Django中展示父分类下的子分类标题及其关联项目?

问题分析与解决

当前你的ItemsByCategoryView仅筛选当前分类直接关联的Item,而父分类下的Item往往挂在子分类/孙分类中,同时模板未处理子分类的层级展示逻辑,导致父分类页面无内容。要实现你需要的层级结构,需从视图和模板两方面修改:

1. 调整视图:覆盖当前分类及所有子分类的Item

修改ItemsByCategoryView的查询逻辑,把当前分类的所有后代分类纳入筛选范围,同时传递分类树给模板:

class ItemsByCategoryView(generic.ListView):
    ordering = 'id'
    paginate_by = 10
    template_name = 'blog/items_by_category.html'

    def get_queryset(self):
        self.category = Category.objects.get(slug=self.kwargs['slug'])
        # 获取当前分类+所有后代分类的ID集合
        category_ids = [self.category.id] + list(self.category.get_descendants().values_list('id', flat=True))
        # 筛选所有归属这些分类的Item,预加载分类避免N+1查询
        queryset = Item.objects.filter(category_id__in=category_ids).select_related('category')
        queryset = queryset.order_by(self.ordering)
        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['category'] = self.category
        # 传递包含当前分类的完整分类树,用于模板层级渲染
        context['category_tree'] = self.category.get_descendants(include_self=True)
        return context

2. 配置MPTT模板标签

在items_by_category.html的内容块开头加载MPTT的模板标签,用于递归渲染分类树:

{% extends "blog/base.html" %}
{% load mptt_tags %} <!-- 新增这行 -->

{% block title %}{{category.name}} list of items{% endblock %}

<!-- 后续内容不变 -->

3. 修改模板:实现层级化分类与Item展示

替换原模板中Item循环的代码块,用递归方式渲染分类层级及对应Item:

<div>
    {% recursetree category_tree %}
        <div style="margin-left: {{ node.level|mul:20 }}px;">
            <!-- 渲染分类名称 -->
            <h3>{{ node.name }}</h3>
            <!-- 渲染当前分类下的Item -->
            {% for item in object_list %}
                {% if item.category == node %}
                    <p><a href="{{ item.get_absolute_url }}">{{ item.title }}</a></p>
                {% endif %}
            {% endfor %}
            <!-- 递归渲染子分类 -->
            {% if not node.is_leaf_node %}
                {{ children }}
            {% endif %}
        </div>
    {% endrecursetree %}
</div>

注:mul是Django内置的乘法过滤器,若未启用需确保django.template.defaultfilters在settings的INSTALLED_APPS中;也可自定义CSS类控制缩进,避免内联样式。

4. 父分类无直接Item的处理

现在父分类页面会自动递归展示所有子分类及其关联的Item,即使父分类本身没有直接绑定Item,也能正常显示层级内容。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:45:35