gpt4 book ai didi

python - 如何在通用 View 中为同一请求使用不同的 Django Rest Framework 序列化程序?

转载 作者:行者123 更新时间:2023-12-04 00:17:46 25 4
gpt4 key购买 nike

我在 API 项目中使用 Django Rest Framework,并试图弄清楚是否有办法将两个不同的序列化器与通用 View (例如 CreateAPIView)一起使用。我想使用一个序列化程序来反序列化 POST 请求,使用另一个序列化程序来序列化结果响应。

这就是我想要做的;我将使用文档中的专辑/轨道示例进行说明:

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

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 View 允许您指定 serializer_class或覆盖 get_serializer_class方法,但我不知道如何使用它来完成我所追求的。

有什么明显的我遗漏了吗?这似乎是一件合理的事情,但我似乎无法理解如何完成它。

最佳答案

方法#1

覆盖 DRF 中的通用 mixin 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()
MultipleSerializersViewMixin取自 django-rest-framework-braces .

方法#2

定制 to_representationCreateAlbumSerializer .例如:
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,尽管它更冗长,因为它不会将任何自定义创建/响应逻辑泄漏给序列化程序。我认为序列化程序应该只知道如何序列化,并且所有为工作选择不同序列化程序的自定义要求都应该在 View 中完成。

关于python - 如何在通用 View 中为同一请求使用不同的 Django Rest Framework 序列化程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31971123/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com