如何使用其他序列化器反序列化POST请求 [英] How to deserialize POST request using a different Serializer

查看:73
本文介绍了如何使用其他序列化器反序列化POST请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用与从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆