Django REST框架:将附加上下文数据从视图传递到序列化程序

x8diyxa7  于 2023-04-22  发布在  Go
关注(0)|答案(1)|浏览(110)

我有一个Django REST框架视图(generics.GenericAPIView)。在其中,我想将上下文数据(视图接收到的原始请求)传递给序列化器。
根据Serializer - Including extra context in Django Rest Framework 3 not working,我已经覆盖了从Rest Framework的GenericAPIView继承的get_serializer_context()方法。
我的观点是这样的:

class MyView(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 = ... get object from database ...

        serializer = MySerializer(my_instance=my_object, validated_data=request.data)

        if serializer.is_valid():
            logger.warning("MyView/put() - request: " + str(request))
            .... other stuff ...

我的序列化器:

class MySerializer():
    def update(self, my_instance, validated_data):
        logger.warning("MySerializer/update() - context: " + str(self.context))
        ... other stuff ...

我的视图的日志显示存在请求详细信息:

MyView/put() - request: <rest_framework.request.Request: PUT '<URL>'>

...但它们不会传递给序列化程序:

MySerializer/update() - context: {}

我怀疑这是因为get_serializer_context()中的self.request值没有填充,或者与视图的put()方法中提供的值不相同。
我还尝试在序列化器的示例化过程中直接包含上下文数据,如www.example.com所示https://www.django-rest-framework.org/api-guide/serializers/#including-extra-context,但也不起作用-同样,上下文数据没有从视图传递到序列化器。
请问,我如何通过generics.GenericAPIView为单个请求向序列化器提供额外的上下文数据?
非常感谢任何信息。

5uzkadbs

5uzkadbs1#

您直接调用序列化程序类,在这种情况下,您必须手动传递context

class MyView(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):
        instance = self.get_object()
        serializer = MySerializer(
            instance,
            data=request.data,
            partial=False,
            context=self.get_serializer_context()
        )
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

但是,我会考虑使用get_serializer(...)方法来获取序列化程序示例

class MyView(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):
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=False)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

相关问题