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

Django REST Framework:如何从GenericAPIView传递上下文数据到序列化器?

如何通过Django REST Framework的GenericAPIView向序列化器传递上下文数据

问题根源分析

你的代码存在两个核心问题导致上下文无法传递:

  1. 序列化器未继承DRF基类:自定义的MySerializer没有继承rest_framework.serializers.Serializer或ModelSerializer,DRF的序列化器基类才内置了context属性的初始化与传递逻辑,空类无法自动处理上下文。
  2. 序列化器实例化方式错误:
    • 参数名不符合DRF规范:应使用instance而非my_instance,用data而非validated_data(validated_data是序列化器验证后生成的属性,不是初始化参数);
    • 未通过视图的get_serializer()方法实例化,该方法会自动调用get_serializer_context()传递上下文,手动实例化时若不传context参数,上下文会丢失。

修正后的代码实现

1. 修正序列化器

让序列化器继承DRF的基类,确保context属性正常工作:

from rest_framework import serializers
import logging

logger = logging.getLogger(__name__)

class MySerializer(serializers.ModelSerializer):  # 若不是模型序列化,可改用serializers.Serializer
    # 定义你的字段,例如:
    # name = serializers.CharField(max_length=100)

    class Meta:
        model = 你的模型类
        fields = ['需要序列化的字段']

    def update(self, instance, validated_data):
        logger.warning("MySerializer/update() - context: " + str(self.context))
        # 编写你的更新逻辑
        instance.save()
        return instance

2. 修正视图(推荐方式:使用get_serializer()自动传上下文)

通过视图内置的get_serializer()方法实例化序列化器,自动传递上下文:

from rest_framework import generics
from rest_framework.response import Response
import logging

logger = logging.getLogger(__name__)

class MyView(generics.GenericAPIView):
    serializer_class = MySerializer  # 必须指定序列化器类,get_serializer才会生效

    def get_serializer_context(self):
        context = super().get_serializer_context()
        context.update({"original_request": self.request})
        return context

    def put(self, request, *args, **kwargs):
        my_object = self.get_object()  # 或自定义逻辑从数据库获取对象
        serializer = self.get_serializer(instance=my_object, data=request.data)

        if serializer.is_valid(raise_exception=True):
            logger.warning("MyView/put() - request: " + str(request))
            serializer.save()
            # 其他业务逻辑
            return Response(serializer.data)

备选方式:手动传入上下文

若不想使用get_serializer(),可手动获取上下文并传入序列化器:

class MyView(generics.GenericAPIView):
    def get_serializer_context(self):
        context = super().get_serializer_context()
        context.update({"original_request": self.request})
        return context

    def put(self, request, *args, **kwargs):
        my_object = ...  # 从数据库获取对象的逻辑
        context = self.get_serializer_context()
        serializer = MySerializer(instance=my_object, data=request.data, context=context)

        if serializer.is_valid(raise_exception=True):
            logger.warning("MyView/put() - request: " + str(request))
            serializer.save()
            return Response(serializer.data)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:37:21