Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在通用视图中对同一请求使用不同的Django Rest框架序列化程序?_Python_Django_Django Rest Framework - Fatal编程技术网

Python 如何在通用视图中对同一请求使用不同的Django Rest框架序列化程序?

Python 如何在通用视图中对同一请求使用不同的Django Rest框架序列化程序?,python,django,django-rest-framework,Python,Django,Django Rest Framework,我正在一个API项目中使用Django Rest框架,并试图找出是否有一种方法可以将两个不同的序列化程序用于通用视图(例如CreateAPIView)。我想使用一个序列化程序反序列化POST请求,使用另一个序列化程序序列化结果响应 这就是我想要做的;我将使用文档中的唱片集/曲目示例进行说明: 我正在使用的模型有一个外键关系。在API中,我希望在分配关系时能够在请求中包含FK,因此在序列化程序中,我使用PrimaryKeyRelated字段,类似于AlbumSerializer处理与跟踪的关系的方

我正在一个API项目中使用Django Rest框架,并试图找出是否有一种方法可以将两个不同的序列化程序用于通用视图(例如CreateAPIView)。我想使用一个序列化程序反序列化POST请求,使用另一个序列化程序序列化结果响应

这就是我想要做的;我将使用文档中的唱片集/曲目示例进行说明:

我正在使用的模型有一个外键关系。在API中,我希望在分配关系时能够在请求中包含FK,因此在序列化程序中,我使用PrimaryKeyRelated字段,类似于AlbumSerializer处理与跟踪的关系的方式:

class CreateAlbumSerializer(serializers.ModelSerializer):
    tracks = serializers.PrimaryKeyRelatedField(many=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')
但是,在响应中,我希望使用ModelSerializer包含专辑的完整表示,而不仅仅是PK、slug等,类似这样的内容:

class AlbumSerializer(serializers.ModelSerializer):
    tracks = TrackSerializer(many=True, read_only=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')

class TrackSerializer(serializers.ModelSerializer):
    class Meta:
        model = Album
        fields = ('order', 'title', 'duration')
通用DRF视图允许您指定
serializer\u类
或重写
get\u serializer\u类
方法,但我不知道如何使用它来完成我所追求的目标

有什么明显的东西我遗漏了吗?这似乎是我想做的一件合理的事情,但我似乎不知道如何去做。

Approach#1 覆盖DRF
ViewSet
中的通用混合。例如:

class MyViewSet(CreateModelMixin, MultipleSerializersViewMixin, ViewSet):
    serializer_class = CreateAlbumSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        saved = self.perform_create(serializer)
        serializer = self.get_serializer(instance=saved, serializer_class=AlbumSerializer)

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        return serializer.save()
class MyViewSet(CreateModelMixin, ViewSet):
    serializer_class = CreateAlbumSerializer

class CreateAlbumSerializer(serializers.ModelSerializer):
    tracks = serializers.PrimaryKeyRelatedField(many=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')

    def to_representation(self, instance):
        data = super(CreateAlbumSerializer, self).to_representation(instance)
        data['tracks'] = TrackSerializer(instance=instance.tracks).data
        return data
MultipleSerializerViewMixin
取自

进近#2 将
自定义为
CreateAlbumSerializer
的\u表示形式。例如:

class MyViewSet(CreateModelMixin, MultipleSerializersViewMixin, ViewSet):
    serializer_class = CreateAlbumSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        saved = self.perform_create(serializer)
        serializer = self.get_serializer(instance=saved, serializer_class=AlbumSerializer)

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        return serializer.save()
class MyViewSet(CreateModelMixin, ViewSet):
    serializer_class = CreateAlbumSerializer

class CreateAlbumSerializer(serializers.ModelSerializer):
    tracks = serializers.PrimaryKeyRelatedField(many=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')

    def to_representation(self, instance):
        data = super(CreateAlbumSerializer, self).to_representation(instance)
        data['tracks'] = TrackSerializer(instance=instance.tracks).data
        return data
比较 我个人喜欢方法#1而不是#2,尽管它更详细,因为它不会向序列化程序泄漏任何自定义创建/响应逻辑。我认为序列化程序应该只知道如何序列化,所有为工作选择不同序列化程序的自定义需求都应该在视图中完成