Django REST Framework: how serializer context works?

后端 未结 2 1189
-上瘾入骨i
-上瘾入骨i 2021-02-13 14:31

It\'s a pretty standard task in Django REST Framework to supply additional args/kwargs to a serializer to set values of fields set not via reques

相关标签:
2条回答
  • 2021-02-13 14:48

    Whenever you use generic views or viewsets, DRF(3.3.2) adds request object, view object and format to the serializer context. You can use serializer.context to access, lets say request.user in the serializer.

    This is added when get_serializer_class() is called. Inside that, it calls get_serializer_context() method where all these parameters are added to its context.

    DRF source code for reference:

    class GenericAPIView(views.APIView):
        """
        Base class for all other generic views.
        """
    
        def get_serializer(self, *args, **kwargs):
            """
            Return the serializer instance that should be used for validating and
            deserializing input, and for serializing output.
            """
            serializer_class = self.get_serializer_class()
            kwargs['context'] = self.get_serializer_context()
            return serializer_class(*args, **kwargs)    
    
        def get_serializer_context(self):
            """
            Extra context provided to the serializer class.
            """
            return {
                'request': self.request,
                'format': self.format_kwarg,
                'view': self
            }
    
    0 讨论(0)
  • 2021-02-13 14:53

    to set values of fields set not via request.data, but via the value in url parameters or cookies. For instance, I need to set user field of my Comment model equal to request.user upon POST request.

    This is how I handle both cases in my ModelViewSet:

    def perform_create(self, serializer):
    
        # Get article id from url e.g. http://myhost/article/1/comments/
        # obviously assumes urls.py is setup right etc etc
        article_pk = self.kwargs['article_pk']
        article = get_object_or_404(Article.objects.all(), pk=article_pk)
    
        # Get user from request
        serializer.save(author=self.request.user, article=article)
    

    Unfortunately the nested objects is not standard for DRF but that's besides the point. :)

    0 讨论(0)
提交回复
热议问题