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

DRF 序列化器上下文添加delivery_date后嵌套序列化器取值失败

修复步骤(按问题影响优先级排序)

1. 核心致命问题:重写get_serializer_context缺少返回逻辑

DRF的get_serializer_context方法的作用是生成传递给所有关联序列化器的公共上下文,你在完成自定义字段的写入后,没有把修改后的上下文对象返回,导致整个序列化流程拿到的上下文根本不包含你添加的delivery_date字段。

对应修复后的视图代码:

class FoodRetrieveAPIView(RetrieveAPIView):
    serializer_class = serializers.FoodRetrieveSerializer
    permission_classes = [IsAuthenticated]
    queryset = models.Food.objects.all()

    def get_serializer_context(self):
        context = super().get_serializer_context()
        query_params = self.request.query_params
        delivery_date = query_params.get("delivery_date")
        context["delivery_date"] = delivery_date
        # 必须返回修改后的context,否则自定义上下文不会生效
        return context

2. 代码语法类问题排查

(1)序列化器父类拼写错误

定义ItemValueRetrieveSerializer时,父类写为serializer.ModelSerializer,缺少复数形式的s,正确写法为serializers.ModelSerializer,否则类定义直接触发报错,序列化流程无法正常执行。

(2)方法缩进不符合Python规范

FoodItemSerializer.get_item方法的方法体没有做标准缩进,会直接触发IndentationError,导致嵌套序列化的逻辑完全无法运行。

3. 嵌套序列化器的上下文透传验证

完成上面两处核心问题修复后,你原有的手动传递context的逻辑是可以正常生效的:外层的FoodItemSerializer拿到包含delivery_date的完整上下文后,在get_item方法里手动实例化ItemValueRetrieveSerializer时传入context=self.context,就能把上下文完整传递到最内层的序列化器中。

如果仍然存在取值异常,可以在get_value方法里加临时打印验证上下文内容:

def get_value(self, obj):
    # 临时打印验证上下文是否包含目标字段
    print("当前序列化器上下文内容:", self.context)
    delivery_date = self.context.get("delivery_date")
    food_value = obj.get_food_value(delivery_date=delivery_date)

可选优化方案

如果不想在每个嵌套的SerializerMethodField里重复手动传递context,可以把嵌套的序列化器直接作为字段声明,DRF会自动完成外层上下文的透传,不需要手动写传递逻辑:

class FoodItemSerializer(serializers.ModelSerializer):
    # 通过source指定关联的模型方法,直接关联子序列化器
    item = ItemValueRetrieveSerializer(source="get_item")

这种方式和手动实例化传递context的效果完全一致,还能减少冗余代码。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 01:54:07