python - Django Rest Framework-我可以在序列化程序的创建方法中允许 pk id 或完整对象吗?
问题描述
假设我有以下模型:
class Author(models.Model):
first_name = models.CharField(max_length=32)
last_name = models.CharField(max_length=32)
class Book(models.Model):
title = models.CharField(max_length=64)
author = models.ForeignKeyField(Author, on_delete=models.CASCADE)
我有以下序列化程序:
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ('id', 'title', 'author')
read_only_fields = ('id')
如果我然后查询我的书,一本书的数据如下所示:
{
"id": 1,
"title": "Book Title",
"author": 4
}
这就是我想要的,因为我返回了一系列书籍以及一系列作者,并允许客户加入所有内容。这是因为我有很多作者在书中重复出现。
但是,我希望允许客户提交现有的作者 ID 以创建新书,或提交新作者的所有数据。例如:
现有作者的新书有效载荷:
{
"title": "New Book!",
"author": 7
}
或者,新作者的新书的有效载荷:
{
"title": "New Book!",
"author": {
"first_name": "New",
"last_name": "Author"
}
}
但是第二个版本不会通过我的序列化程序中的数据验证步骤。有没有办法覆盖验证步骤,允许作者 ID 或完整对象?然后在我的序列化程序的创建方法中,我可以检查类型,或者创建一个新作者,获取它的 id,然后创建新书,或者只是附加现有的 id。想法?
解决方案
我相信不可能以您想要的方式(使用一个字段author
)进行操作。
只是因为一个序列化程序无法为一个字段处理两种不同的类型。
注意:我可能对前面的陈述有误。
但是,以下是您的潜在解决方案。您只需要使用不同的字段名称来创建新作者。
class BookSerializer(serializers.ModelSerializer):
author = serializers.PrimaryKeyRelatedField(
required=False,
queryset=Author.objects.all(),
)
author_add = AuthorSerializer(write_only=True, required=False)
class Meta:
model = Book
fields = ('id', 'title', 'author', 'author_add')
read_only_fields = ('id')
def create(self, validated_data):
author_add_data = validated_data.pop('author_add', None)
if author_add is not None:
validated_data['author'] = Author.objects.create(**author_add_data)
return super().create(validated_data)
注意:您需要处理同时发送author
和的情况author_add
。如果两者都提供,可能会在验证步骤中添加检查并引发 ValidationError。
题外话提示:您不需要明确状态read_only_fields = ('id',)
- 主键是只读的。
推荐阅读
- mongodb - 从 mongodb 4.0 中删除重复记录
- node.js - 如何将 ssl private-key.txt 转换为 private.key 扩展名
- c# - Xamarin 在页面之间传递参数
- c# - C# xls & xlsx 查询从工作表中选择,而不考虑工作表名称
- c# - Cortana 是否支持 webhook/调用外部 API?
- php - 内核中的身份验证声明和 laravel 中的路由无法正常工作
- emacs - 如何在 magit 中暂存/提交当前缓冲区?
- java - 从 JDBC 连接到 MSSQL 服务器时出现 Windows 身份验证问题
- java - FLAG_DIM_BEHIND 导致 android oreo 滞后
- kotlin - 需要改进“非常尴尬”的 Rx 逻辑来组合不同的数据源