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

如何在Django MPTT模型中使用django-filters实现分类深度过滤

解决方案

核心思路

利用MPTT模型自带的get_descendants()方法,获取目标分类及其所有子分类的ID集合,再通过该集合过滤关联的产品。

步骤实现

1. 确认模型结构(参考示例)

假设你的模型定义如下:

# models.py
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey

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

    class MPTTMeta:
        order_insertion_by = ['name']

class Product(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')

2. 重写过滤器的分类名称过滤逻辑

修改filters.py中的ProductFilter,自定义分类名称的过滤方法:

# filters.py
import django_filters
from .models import Product, Category

class ProductFilter(django_filters.FilterSet):
    # 用method参数指定自定义过滤函数
    category_name = django_filters.CharFilter(method='filter_category_with_descendants')

    def filter_category_with_descendants(self, queryset, name, value):
        # 匹配目标分类(忽略大小写)
        target_cats = Category.objects.filter(name__iexact=value)
        if not target_cats.exists():
            return queryset.none()
        
        # 收集目标分类及其所有子分类的ID
        descendant_ids = []
        for cat in target_cats:
            # include_self=True 包含分类自身
            descendant_ids.extend(cat.get_descendants(include_self=True).values_list('id', flat=True))
        
        # 去重后过滤产品
        descendant_ids = list(set(descendant_ids))
        return queryset.filter(category_id__in=descendant_ids)

    class Meta:
        model = Product
        fields = ['category_name']

3. 视图配置保持不变

你的views.py无需修改,只要确保已绑定该过滤器和DjangoFilterBackend:

# views.py
from rest_framework import generics
from .models import Product
from .filters import ProductFilter
from rest_framework.filters import DjangoFilterBackend

class ProductAPIView(generics.ListAPIView):
    queryset = Product.objects.all()
    filter_backends = [DjangoFilterBackend]
    filterset_class = ProductFilter

关键说明

  • get_descendants(include_self=True):MPTT模型提供的方法,能快速获取当前分类的所有子分类(含自身)
  • 自定义过滤方法:绕过默认的精确匹配,改为基于分类树的批量ID过滤
  • 多同名分类处理:如果存在多个同名分类,会自动收集所有对应分类及其子分类的产品

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 05:05:17