Python Django REST框架的POST/PUT深度不同?
我正在使用Django REST框架为我的web应用程序创建API。我有一个类“Comment”,它在Python Django REST框架的POST/PUT深度不同?,python,django,rest,django-rest-framework,Python,Django,Rest,Django Rest Framework,我正在使用Django REST框架为我的web应用程序创建API。我有一个类“Comment”,它在Meta类中设置了depth=2。这在获取注释时非常有效。当我尝试发送POST或PUT请求时(即创建新的注释),我被告知需要包含对象,而不是外键ID 下面是我的序列化程序类: class CommentSerializer(serializers.ModelSerializer): class Meta: model = Comment depth = 2
Meta
类中设置了depth=2
。这在获取注释时非常有效。当我尝试发送POST
或PUT
请求时(即创建新的注释
),我被告知需要包含对象,而不是外键ID
下面是我的序列化程序类:
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
depth = 2
模型:
class Comment(models.Model):
user = models.ForeignKey(User, null=True, blank=True,
related_name='comments')
budget = models.ForeignKey(Budget, related_name='comments')
published = models.BooleanField(default=False)
body = models.TextField()
created = models.DateTimeField(auto_now_add=True)
查看代码:
class Comments(generics.ListCreateAPIView):
model = Comment
serializer_class = CommentSerializer
def pre_save(self, obj):
obj.user = self.request.user
输出(JSON)中显示的错误是:
发送此原始数据时:
{"budget": 2, "published": true, "body": "Another comment"}
我认为定义引用外键关系的序列化程序字段的正确方法是通过类似于序列化程序.PrimaryKeyRelatedField
的方式。我不相信模型序列化程序在没有在序列化程序类中显式定义它的情况下自动使用这个字段类
我可以想象一个PrimaryKeyRelatedField
序列化程序可以正确处理JSON数据提交,就像您在示例中使用的那样。我知道这有点晚,但我最终使用了两个序列化程序,如下所示:
class CommentReadSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
depth = 2
class CommentWriteSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
然后像这样使用:
class Comments(generics.ListCreateAPIView):
model = Comment
serializer_class = CommentReadSerializer
def create(self, request, *args, **kwargs):
serializer = CommentWriteSerializer(data=request.DATA, files=request.FILES)
if serializer.is_valid():
self.pre_save(serializer.object)
self.object = serializer.save(force_insert=True)
self.post_save(self.object, created=True)
headers = self.get_success_headers(serializer.data)
serializer = CommentReadSerializer(serializer.object)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
您可以通过重写get\u serializer\u class()
函数来设置不同的序列化程序,如下所示:
def get_serializer_类(self):
方法=self.request.method
如果方法='PUT'或方法='POST':
返回WriteSerializer
其他:
返回您的ReadSerializer
我想加上这个,因为我在谷歌搜索了一段时间后来到这里。随机问题,如果你发送{“budget\u id”:2}
或{“budget”:{“id”:2}
?RE@Nathan Villaescusa怎么办。对于那些从谷歌来到这里的人,汤姆·克里斯蒂(DRF的创建者)在这里写了更多关于这一点的文章:迄今为止最好最简单的回答。
class Comments(generics.ListCreateAPIView):
model = Comment
serializer_class = CommentReadSerializer
def create(self, request, *args, **kwargs):
serializer = CommentWriteSerializer(data=request.DATA, files=request.FILES)
if serializer.is_valid():
self.pre_save(serializer.object)
self.object = serializer.save(force_insert=True)
self.post_save(self.object, created=True)
headers = self.get_success_headers(serializer.data)
serializer = CommentReadSerializer(serializer.object)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)