英文:
Django REST framework: passing additional contextual data from view to serializer
问题
I have a Django REST framework view (generics.GenericAPIView
). In it, I want to pass contextual data (the original request received by the view) to a serializer.
As per https://stackoverflow.com/questions/52188500/serializer-including-extra-context-in-django-rest-framework-3-not-working, I've overridden the get_serializer_context()
method inherited from Rest Framework's GenericAPIView
.
My view looks like this:
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 the database ...
serializer = MySerializer(my_instance=my_object, validated_data=request.data)
if serializer.is_valid():
logger.warning("MyView/put() - request: " + str(request))
.... other stuff ...
My serializer:
class MySerializer():
def update(self, my_instance, validated_data):
logger.warning("MySerializer/update() - context: " + str(self.context))
... other stuff ...
My view's logs show that the request details are present:
MyView/put() - request: <rest_framework.request.Request: PUT '<URL>'>
... but they are not passed to the serializer:
MySerializer/update() - context: {}
I'm suspecting that it's because the self.request
value in get_serializer_context()
is not populated or is not the same as the one supplied in the view's put()
method.
I've also tried including the context data directly during the instantiation of the serializer, as per https://www.django-rest-framework.org/api-guide/serializers/#including-extra-context but that didn't work either - again, the contextual data was not passed from the view to the serializer.
How can I supply the additional contextual data to the serializer for individual requests via generics.GenericAPIView
, please?
Many thanks for any information.
英文:
I have a Django REST framework view (generics.GenericAPIView
). In it, I want to pass contextual data (the original request received by the view) to a serializer.
As per https://stackoverflow.com/questions/52188500/serializer-including-extra-context-in-django-rest-framework-3-not-working, I've overridden the get_serializer_context()
method inherited from Rest Framework's GenericAPIView
.
My view looks like this:
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 ...
My serializer:
class MySerializer():
def update(self, my_instance, validated_data):
logger.warning("MySerializer/update() - context: " + str(self.context))
... other stuff ...
My view's logs shows that the request details are present:
MyView/put() - request: <rest_framework.request.Request: PUT '<URL>'>
... but they are not passed to the serializer:
MySerializer/update() - context: {}
I'm suspecting that it's because the self.request
value in get_serializer_context()
is not populated or is not the same as the one supplied in the view's put()
method.
I've also tried including the context data directly during the instantiation of the serializer, as per https://www.django-rest-framework.org/api-guide/serializers/#including-extra-context but that didn't work either - again, the contextual data was not passed from the view to the serializer.
How can I supply the additional contextual data to the serializer for individual requests via generics.GenericAPIView
, please?
Many thanks for any information.
答案1
得分: 2
你正在直接调用序列化器类,并在这种情况下需要手动传递context
。
但我会考虑使用get_serializer(...)
方法来获取序列化器实例。
英文:
You are calling the serializer class directly and in that situation you have to pass the context
manually
<pre><code>
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()
<b>serializer = MySerializer(
instance,
data=request.data,
partial=False,
context=self.get_serializer_context()
)</b>
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
</code></pre>
But, I would consider using the get_serializer(...)
method to get the serializer instance
<pre><code>
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()
<b>serializer = self.get_serializer(instance, data=request.data, partial=False)</b>
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
</code></pre>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论