Django Rest Framework - 基于模型的API视图中的每个方法单独的序列化程序类

时间:2014-07-09 08:33:52

标签: django-rest-framework swagger

假设我有一个简单的Django REST Framework视图,该视图扩展了多个模型类并为一个URL端点中的所有方法提供服务:

class UserAPIView(RetrieveAPIView, DestroyAPIView, BaseObjectAPIView):
    permission_classes = (IsAuthenticated, )
    serializer_class = UserSerializer

    def get_serializer_class(self, *args, **kwargs):
        # return different serializer depending on method??            
        # return UserUpdateSerializer
        return UserViewSerializer

    def get(self, request, *args, **kwargs):
        """
        Retrieve user details
        """
        # ...
        return Response(data={'result': "OK"}, status=200)

    def delete(self, request, pk):
        """
        Delete user
        """
        # ...
        return Response(data={'result': "OK"}, status=200)

    def put(self, request, pk):
        """
        Change user
        """
        # ...        
        return Response(data={'result': "OK"}, status=200)

现在我需要为每个方法使用不同的序列化器,因为我的get-method将使用与put-method不同的字段,例如序列化器:

class UserViewSerializer(serializers.ModelSerializer):
    firstname = serializers.Field(source='firstname')
    lastname = serializers.Field(source='lastname')
    username = serializers.Field(source='username')

    class Meta:
        model = User

class UserUpdateSerializer(serializers.ModelSerializer):
    firstname = serializers.Field(source='firstname')
    lastname = serializers.Field(source='lastname')    

    class Meta:
        model = User

是否可以在基于模型的API视图中为每种方法使用不同的序列化器?

更新

我知道如何在方法本身内使用不同的序列化器。

但是我需要获得Swagger(Django模块rest_framework_swagger)生成的Browsable API来为每个方法检索不同的序列化器。 我可以看到加载API浏览器页面会触发get_serializer_class,但在该方法中,我不知道Swagger试图获取序列化器的方法。

如何让rest_framework_swagger为每种方法检索不同的序列化器?

2 个答案:

答案 0 :(得分:10)

我认为至少有两种方法可以实现这一目标:

  1. 您只需在每种方法中设置所需的序列化程序。像这样:

    def get(self, request, *args, **kwargs):
        self.serializer_class = UserViewSerializer
        # ...
        return Response(data={'result': "OK"}, status=200) 
    
  2. 您覆盖 get_Serializer_class 方法。像这样:

    def get_serializer_class(self, *args, **kwargs):
        if self.request.method == 'POST':
            return UserUpdateSerializer
        return UserViewSerializer
    
  3. 希望这有帮助。

答案 1 :(得分:2)

我想你可以在每个方法上使用yaml docstring来覆盖序列化程序。像:

def put(self, request, pk):
    """Change user

    ---
    serializer: .serializers.UserUpdateSerializer
    """
    # ...
    return Response(data={'result': "OK"}, status=200)