Use different serializers for input and output from a service

后端 未结 2 937
小鲜肉
小鲜肉 2021-02-01 06:50

A default DRF resource is limited to accepting the same object it later returns. I want to use a different serializer for the input than the output. For example, I want to imp

相关标签:
2条回答
  • 2021-02-01 07:01

    One of the solutions is TastyPie for Django, which has eg.:

    • Resource.alter_deserialized_detail_data() - allowing you to alter incoming single resource structure before interpreting it further,
    • Resource.alter_detail_data_to_serialize() - allowing you to alter outbound single resource structure before serialization,

    Similar is true when serializing / de-serializing lists: Resource.alter_deserialized_list_data() and Resource.alter_list_data_to_serialize().

    Note: But I believe something similar is (or will be) possible with Django REST Framework. DRF is relatively new, and recently faced some significant refactoring. Django REST Framework has pretty good opinion in Django community, and seemingly has insightful development team, so maybe you should think asking their developers or proposing improvements. Of course, if you won't find any help on StackOverflow (or encounter some answers from DRF developers here).

    0 讨论(0)
  • 2021-02-01 07:15

    My problem is that I want to have different serializers for input and output of a service.

    It's easy enough to have different serializers for different request methods (eg something to response to GET requests that's different to PUT, POST etc...)

    Just override get_serializer_class(), and return a different serializer class depending on the value of self.request.method.

    That may not be exactly what you're looking for because when you PUT or POST data you'll still end up with the same output style as you supplied.

    In that case you should probably just write the view explicitly rather than relying on the default generic views, something along these lines...

    class UserCreateOrListView(views.APIView):
        def get(self, request, *args, **kwargs):
            serializer = ImaginaryUserOutputSerializer(User.objects.all())
            return Response(serializer.data)
    
        def post(self, request, *args, **kwargs):
             serializer = ImaginaryUserInputSerializer(data=request.DATA)
             if serializer.is_valid():
                 user = serializer.save()
                 output_serializer = ImaginaryUserOutputSerializer(user)
                 return Response(output_serializer.data)
             else:
                 return Response(serializer.errors, 400)
    
    etc...
    

    It's also worth asking on the mailing list as other users may be doing something similar and have useful patterns to share.

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