Python 如何在通用视图中对同一请求使用不同的Django Rest框架序列化程序?
我正在一个API项目中使用Django Rest框架,并试图找出是否有一种方法可以将两个不同的序列化程序用于通用视图(例如CreateAPIView)。我想使用一个序列化程序反序列化POST请求,使用另一个序列化程序序列化结果响应 这就是我想要做的;我将使用文档中的唱片集/曲目示例进行说明: 我正在使用的模型有一个外键关系。在API中,我希望在分配关系时能够在请求中包含FK,因此在序列化程序中,我使用PrimaryKeyRelated字段,类似于AlbumSerializer处理与跟踪的关系的方式:Python 如何在通用视图中对同一请求使用不同的Django Rest框架序列化程序?,python,django,django-rest-framework,Python,Django,Django Rest Framework,我正在一个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
覆盖DRFViewSet
中的通用混合。例如:
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,尽管它更详细,因为它不会向序列化程序泄漏任何自定义创建/响应逻辑。我认为序列化程序应该只知道如何序列化,所有为工作选择不同序列化程序的自定义需求都应该在视图中完成