考虑这种情况,我有一个Book
和Author
模型。
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')
我的序列化程序对于
POST
,PUT
,PATCH
请求看起来像这样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上查看我类似的问题和解决方案