如何使用其他序列化器反序列化POST请求 [英] How to deserialize POST request using a different Serializer
问题描述
我正在尝试使用与从Model派生并用于GET或PUT请求的序列化程序不同的序列化程序,在API端点中处理POST请求。 POST消息的格式与Model和GET / PUT不同,并且在存储到数据库之前必须进行预处理。
I'm trying to handle POST requests in my API endpoint using a different serializer than the one derived from Model and used for GET or PUT requests. The format of the POSTed messages is different from the Model and from GET/PUT and must be pre-processed before storing to the database.
作为我的问题的演示,我制作了一个非常简单的模型以及相应的API视图和序列化器:
As a demo of my problem I made a very simple model and the corresponding API view and serializer:
class Message(models.Model):
message = models.CharField(max_length = 500)
class MessageSerializer(serializers.ModelSerializer):
class Meta:
model = Message
fields = ('message',)
class MessageViewSet(viewsets.ModelViewSet):
queryset = Message.objects.all().order_by('-pk')
serializer_class = MessageSerializer
效果很好。然后,我尝试覆盖MessageViewSet.create()以不同方式处理POST请求。
That works well. Then I tried to override the MessageViewSet.create() to handle POST requests differently.
class MessageSerializer_FromTo(serializers.Serializer):
sender = serializers.EmailField()
recipient = serializers.EmailField()
def create(self, validated_data):
message = "Message from <{sender}> to <{recipient}>".format(**validated_data)
return Message(message)
class MessageViewSet(viewsets.ModelViewSet):
queryset = Message.objects.all().order_by('-pk')
serializer_class = MessageSerializer
# Handle POST requests differently
def create(self, request, format=None):
message = MessageSerializer_FromTo(data = request.data)
if message.is_valid():
message.save()
return Response(message.data, status=status.HTTP_201_CREATED)
return Response(message.errors, status=status.HTTP_400_BAD_REQUEST)
基本上我想将此JSON传递给POST / ap i / messages /
Essentially I want to pass this JSON to POST /api/messages/
{"sender": "some@one.com", "recipient": "someone@else.org"}
GET / api / messages / 1 /应该返回
GET /api/messages/1/ should return
{"message": "Message from <some@one.com> to <someone@else.org>"}
但是POST失败并显示以下消息:
However the POST fails with this message:
Internal Server Error: /api/messages/
Traceback (most recent call last):
File ".../rest_framework/fields.py", line 441, in get_attribute
return get_attribute(instance, self.source_attrs)
File ".../rest_framework/fields.py", line 100, in get_attribute
instance = getattr(instance, attr)
AttributeError: 'Message' object has no attribute 'sender'
During handling of the above exception, another exception occurred:
[...]
AttributeError: Got AttributeError when attempting to get a value for field `sender` on serializer `MessageSerializer_FromTo`.
The serializer field might be named incorrectly and not match any attribute or key on the `Message` instance.
Original exception text was: 'Message' object has no attribute 'sender'.
[26/Feb/2018 05:09:08] "POST /api/messages/ HTTP/1.1" 500 19059
这显然是为了说明问题,我在POST中做的事情比较复杂处理程序,但错误是这样的。
This is just to demonstrate the problem obviously, I'm doing more complex things in my POST handler, but the error is like this.
有什么想法可以实现我所需要的吗?即接受与Model字段完全不同的POST字段吗?
Any idea how to achieve what I need? I.e. accept POST fields that are completely different from the Model fields?
谢谢!
更新:完整代码在这里: https://github.com/mludvig/drf-demo
推荐答案
问题出现在序列化程序中。您只是传递模型类 Message(message)
作为create函数的输出而不是Message对象
problem is with in your serializer. You are just passing model class Message(message)
as the output of create function instead of Message object
class MessageSerializer_FromTo(serializers.Serializer):
sender = serializers.EmailField(write_only=True)
recipient = serializers.EmailField(write_only=True)
message = serializers.CharField(read_only=True, max_length = 500)
def create(self, validated_data):
message = "Message from <{sender}> to <{recipient}>".format(**validated_data)
return Message.objects.create(message=message)
这篇关于如何使用其他序列化器反序列化POST请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!