考虑这种情况,我有一个BookAuthor模型。

serializers.py

class AuthorSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.Author
        fields = ('id', 'name')

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer(read_only=True)

    class Meta:
        model = models.Book
        fields = ('id', 'title', 'author')


viewsets.py

class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer


如果我发送GET书籍请求,则效果很好。我得到的输出带有嵌套的序列化器,该序列化器包含我想要的书籍详细信息和嵌套的作者详细信息。

但是,当我想创建/更新一本书时,我必须发送一个POST / PUT / PATCH,其中包含作者的嵌套详细信息,而不仅仅是他们的ID。我希望能够通过指定作者ID而不是整个作者对象来创建/更新书对象。

因此,对于GET请求,我的序列化程序看起来像这样

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer(read_only=True)

    class Meta:
        model = models.Book
        fields = ('id', 'title', 'author')


我的序列化程序对于POSTPUTPATCH请求看起来像这样

class BookSerializer(serializers.ModelSerializer):
    author = PrimaryKeyRelatedField(queryset=Author.objects.all())

    class Meta:
        model = models.Book
        fields = ('id', 'title', 'author')


我也不想为每种类型的请求创建两个完全独立的序列化器。我只想修改author中的BookSerializer字段。

最后,是否有更好的方法来完成这件事?

最佳答案

恕我直言,多个序列化器只会造成越来越多的混乱。

而是我更喜欢下面的解决方案:


不要更改您的视图集(保留默认设置)
在序列化器中添加.validate()方法;以及其他必需的.create或.update()等。在这里,真正的逻辑将进入
validate()方法。根据请求类型,我们将在哪里创建
串行器要求的validated_data字典。


我认为这是最干净的方法。

DRF: Allow all fields in GET request but restrict POST to just one field上查看我类似的问题和解决方案

10-05 20:49
查看更多