django - Django 的 DRF ModelViewSet 中 CREATE 的可选 pk 参数
问题描述
我的一个模型有一个常规的 ModelViewSet,但我希望可以选择指定一个特定的 PK 来创建一个新实例。例如,如果我要发布:
{
"name": "Name"
}
它会得到一个随机的pk。但是,如果我发布:
{
"id": "123",
"name": "Name"
}
我希望它具有指定的 pk (id)。
与此人类似,我所做的是将id
字段添加到我的 ModelSerializer 中,如下所示:
class ConversationViewSet(viewsets.ModelViewSet):
"""
List all conversations, or create new / edit existing product.
"""
queryset = Conversation.objects.all()
serializer_class = ConversationSerializer
class ConversationSerializer(serializers.ModelSerializer):
id = serializers.CharField(required=False) # Instead of serializer.ReadOnlyField()
class Meta:
model = Conversation
fields = '__all__'
虽然这适用于该create
方法,但它会导致update
andpartial_update
的问题,现在 whereid
是作为查询字符串参数的必需参数,并且在请求正文中像这样(来自文档):
update
PUT /conversations/{id}/
Update existing conversation.
Path Parameters
The following parameters should be included in the URL path.
Parameter Description
id (required) A unique value identifying this conversation.
Request Body
The request body should be a "application/json" encoded object, containing the following items.
Parameter Description
id
access_token
username
password
app_user_id
name
当然,拥有两个同名的参数是不好的做法。例如,当使用requests
和传递参数字典时,它不再起作用,因为它不知道我正在处理哪个参数。
我该如何解决这个问题,使id
参数仅对该create
方法是可选的,但所有其他方法(列表、读取、...)与默认情况下保持完全相同?
我的解决方案
根据 JPG 的回答,我将序列化程序修改为:
class ConversationSerializer(serializers.ModelSerializer):
id = serializers.ReadOnlyField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.context['view'].action == 'create':
self.fields['id'] = serializers.CharField(required=False)
class Meta:
model = Conversation
fields = '__all__'
解决方案
我认为这可以通过覆盖__init__()
序列化程序的方法来实现。
class ConversationSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.context['view'].action == 'create':
self.fields['id'] = serializers.CharField()
else:
self.fields['id'] = serializer.ReadOnlyField()
class Meta:
model = Conversation
fields = '__all__'
推荐阅读
- javascript - [单元测试]:如何在具有模拟 axios 调用的点击事件后获取更新的道具
- python - 基于另一个参考附加
- python - 根据 Pandas 中的其他变量结果填充新变量的更有效方法是什么
- java - 如何解决 jhipster 的元空间问题?
- javascript - 如何随机分配网页图标?
- sql - 如何在plsql中将字符串数据类型传递给数字数据类型
- php - 在多维数组中分组唯一值
- ruby-on-rails - 无法从领英获取身份验证信息
- python - 如何在 Django 中显示 ManyToMany 字段的值而不是它们的 Id?
- java - 您的应用程序已使用来自 translate.googleapis.com 的 Google Cloud SDK 的最终用户凭据进行身份验证