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

如何在Django序列化器中过滤ManyToManyField并按分类返回对应服务

问题原因

你当前直接在VariantServiceSerializer中用source='service_id'序列化多对多字段时,会返回该变体关联的所有服务,不会自动匹配外层的分类条件,因此出现了跨分类的服务数据。

解决方案

第一步:修改CategoryServiceListSerializer,向子序列化器传递当前分类上下文

调整get_variant方法,把当前遍历的分类实例通过序列化器上下文传递给内层:

def get_variant(self, instance):
    variant_id = self.context.get('variant_id')
    if variant_id:
        variants = instance.variant_set.filter(pk=variant_id)
    else:
        variants = instance.variant_set.all()
    # 新增context参数传递当前分类实例,同时保留原有上下文
    return VariantServiceSerializer(variants, many=True, context={'category': instance, **self.context}).data

第二步:修改VariantServiceSerializer,用SerializerMethodField过滤服务

替换原有直接序列化多对多字段的逻辑,新增过滤逻辑:

class VariantServiceSerializer(serializers.ModelSerializer):
    services = serializers.SerializerMethodField()

    class Meta:
        model = Variant
        fields = "__all__"

    def get_services(self, obj):
        # 获取上层传递的当前分类实例
        current_category = self.context.get('category')
        # 过滤出该变体下、归属当前分类的服务
        filtered_services = obj.service_id.filter(category_id=current_category)
        # 序列化过滤后的结果返回
        return ServiceListSerializer(filtered_services, many=True).data
实现逻辑说明
  • DRF嵌套序列化不会自动根据外层父对象过滤子字段,需要手动通过context参数传递父级上下文
  • 我们在遍历每个分类时,把当前分类实例传递给内层的变体序列化器,过滤服务时仅保留分类匹配的条目,最终输出就会和预期一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 11:39:03