如何在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
相关产品推荐
相关产品推荐

