知道为什么我不能POST到这个Django REST API?

时间:2014-01-29 14:35:40

标签: django rest django-rest-framework

我目前正在尝试使用运行到Django REST框架的multipart / form-data来获取POST请求。我通过交互式API屏幕成功运行了一些测试请求,这些工作正常。然后我尝试将这些转换为使用非基于会话的auth策略,并且我一直有错误。我发送的请求格式如下:

POST /api/logs/ HTTP/1.1
Host: host:8080
Connection: keep-alive
Content-Length: 258
Accept: application/json
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryTOhRsMbL8ak9EMQB
Authorization: Token -token-

------WebKitFormBoundaryx6ThtBDZxZNUCkKl
Content-Disposition: form-data; name="SubmittedAt"

2014-01-23T10:39:00
------WebKitFormBoundaryx6ThtBDZxZNUCkKl
Content-Disposition: form-data; name="Device"

CheeseDevice
------WebKitFormBoundaryx6ThtBDZxZNUCkKl--

可悲的是,结果是(对于我运行的所有请求):

{"Device": ["This field is required."], "SubmittedAt": ["This field is required."], "LogFile": ["This field is required."]}

有趣的是,我已经能够将JSON块发送到端点,并且它们被按预期接受,例如:

POST /api/logs/ HTTP/1.1
Content-Type: application/json
Host: host:8080
Connection: keep-alive
Content-Length: 35
Accept: application/json
Authorization: Token -token-

{
    "Device": "CheeseDevice"
}

返回:

{"SubmittedAt": ["This field is required."], "LogFile": ["This field is required."]}

正如预期的那样 - 它实际上接受了Device参数,并且仅在缺少的项目上引发错误。我转而使用JSON,但遗憾的是无法用它上传文件......

提前感谢您的帮助!

编辑:

进一步调查(即:编写一个返回请求数据的视图方法,显示request.DATA由于某种原因没有填充。我用来调试的方法如下:

    def test_create(self, request, pk=None):
        return Response(request.DATA)

编辑2:

即使进一步调查(并将代码块丢弃到调试框架中)也表明请求正在_perform_form_overloading中被捕获,并且永远不会访问MultiPartParser。不确定为什么会这样,但我会尝试进一步追踪它。

2 个答案:

答案 0 :(得分:1)

在深入研究每个级别后,我都能找到......

看起来问题源于行结尾 - 即:我一直使用的libs和请求发送者通过“\ n”(LF)结尾发送内容,而HTTP规范要求“\ r \ n”结局(CR,LF)

这取决于Django核心中的以下代码,在http / multipartparser.py中 - 在parse_boundary_stream中:

header_end = chunk.find(b'\r\n\r\n')

出于开发目的(并且因为它在Django端比在客户端更容易修补...)我已将上面的行切换为:

header_end = chunk.replace("\r\n","\n").find(b'\n\n')

这个更新的代码遵循HTTP / 1.1规范第19.3节关于容忍应用程序和接受LF而不仅仅是CRLF的建议 - 我会试着看看它是否适合包含在Django核心中。< / p>

编辑:

作为参考,该补丁已在GitHub上发布:https://github.com/tr00st/django/commit/9cf6075c113dd27e3743626ab0e18c6616488bd9

答案 1 :(得分:0)

这可能是由于格式错误的多部分发布数据造成的。

您也可能没有安装MultiPartParser,但我认为不会这样,因为您通常希望在这种情况下看到415 Unsupported Media Type响应。