Django REST Framework:如何从GenericAPIView传递上下文数据到序列化器?
如何通过Django REST Framework的GenericAPIView向序列化器传递上下文数据
问题根源分析
你的代码存在两个核心问题导致上下文无法传递:
- 序列化器未继承DRF基类:自定义的
MySerializer没有继承rest_framework.serializers.Serializer或ModelSerializer,DRF的序列化器基类才内置了context属性的初始化与传递逻辑,空类无法自动处理上下文。 - 序列化器实例化方式错误:
- 参数名不符合DRF规范:应使用
instance而非my_instance,用data而非validated_data(validated_data是序列化器验证后生成的属性,不是初始化参数); - 未通过视图的
get_serializer()方法实例化,该方法会自动调用get_serializer_context()传递上下文,手动实例化时若不传context参数,上下文会丢失。
- 参数名不符合DRF规范:应使用
修正后的代码实现
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
相关产品推荐
相关产品推荐

