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

使用Django-mptt实现选中分类时展示该分类及所有子分类商品

解决方案

你需要修改视图层的商品过滤逻辑,使用django-mptt自带的后代节点查询方法实现需求,具体改动如下:

1. 修改views.py中的product_list函数

找到分类过滤的代码段,将原有的精确匹配分类逻辑,替换为匹配当前分类+所有子分类:

def product_list(request, category_slug=None):
    category = None
    categories = Category.objects.all()
    products = Product.objects.filter(available=True).order_by('-created')
    if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
        # 新增代码:获取当前分类及所有层级的子分类集合
        target_categories = category.get_descendants(include_self=True)
        # 过滤条件改为商品分类在上述集合中
        products = products.filter(category__in=target_categories)
    return render(request,
                  'shop/shop.html',
                  {'category': category,
                  'categories': categories,
                   'products': products})

逻辑说明

  • get_descendants()是django-mptt提供的内置方法,会单次查询数据库拿到当前节点下所有层级的子节点,符合你使用mptt减少数据库查询的需求
  • 加include_self=True参数是为了同时匹配直接挂在当前分类下的商品,比如如果有商品直接归属于「服装」分类,也会正常显示

2. 可选修正:models.py的缩进问题

你当前贴出的Category类代码存在缩进错误,MPTTMeta和内部的Meta类应该是Category的子类,修正后写法如下:

class Category(MPTTModel):
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True, unique=True)
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')

    # 以下类的缩进调整为Category的内部类
    class MPTTMeta:
        order_insertion_by = ['name']

    class Meta:
        ordering = ('name',)
        verbose_name = 'Категория'
        verbose_name_plural = 'Категории'

    def get_absolute_url(self):
        return reverse('shop:product_list_by_category', args=[self.slug])

    def __str__(self):
        return self.name

前端模板不需要做任何修改,调整完上述代码后即可实现父分类页展示所有子分类商品的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 21:09:03