【问题标题】:django-rest-framework http put failing with 415 on django 1.5django-rest-framework http 在 django 1.5 上使用 415 失败
【发布时间】:2013-02-15 16:15:53
【问题描述】:

我将 django-rest-framework(最新)用于 REST API,并使用内置测试客户端在 django 中实现了一些测试用例。

以下 django 测试用例在 django 版本

self.client.put('/core/accounts/%s/'% self.account.id,
        data = prepare_dict(self.account),
        HTTP_AUTHORIZATION=self.token)

升级到 django 1.5,所有测试都通过了,除了与 HTTP PUT 相关的测试 在调查问题时发现这个@https://docs.djangoproject.com/en/dev/releases/1.5/#options-put-and-delete-requests-in-the-test-client

如果您在 PUT 请求中使用 data 参数而没有 content_type,您必须在将数据传递给测试之前对其进行编码 客户端并设置 content_type 参数。

因此,更新了我的测试以反映此更改并尝试遵循,但仍然获得 http 415 而不是 http 200

from django.test.client import MULTIPART_CONTENT, BOUNDARY, encode_multipart
self.client.put('/core/accounts/%s/'% self.account.id,
            data = encode_multipart(BOUNDARY, prepare_dict(self.account)),
                content_type=MULTIPART_CONTENT,
        HTTP_AUTHORIZATION=self.token)

知道我错过了什么吗? P.S:django-rest-framework 内置 Web UI 的所有功能都可以正常工作

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    您绝对走在正确的轨道上 - 在这种情况下,破坏性测试肯定是由于 Django 更改了测试客户端的 PUT 行为。

    你的修复看起来对我来说也是正确的。 415 是“不支持的媒体类型”响应,这意味着请求内容类型不是为视图配置的任何解析器都可以处理的内容。

    通常在这种情况下,那是由于忘记设置请求的内容类型,但看起来您已正确设置为multipart/form-data; boundary=...

    需要仔细检查的事项:

    • 究竟response.data 显示的错误详细信息是什么?
    • 你在DEFAULT_PARSER_CLASSES 设置中配置了什么(如果有的话),或者你在视图属性parser_classes 上设置了什么?
    • 确保在测试中content_type 中没有错字(即使这里是正确的)。

    编辑

    感谢您的 cmets - 这一切都清楚了。您只安装了 JSON 解析器,但您正在尝试发送表单编码数据。您应该:

    • FormParserMultiPartParser 添加到您的设置/视图,使其支持表单编码。 (另请注意,默认的DEFAULT_PARSER_CLASSES 设置确实包含它们,因此如果您根本不设置任何内容,它会按预期工作)

    或者

    • 在您的测试用例中使用json 编码而不是表单编码对请求进行编码...data=json.dumps(prepare_dict(self.account)), content_type='application/json'

    【讨论】:

    • Tom,首先感谢 djnago-rest-framework。正如你所问的,我仔细检查了。 response.data = {u'detail': u"不支持的媒体类型 'multipart/form-data;boundary=BoUnDaRyStRiNg' in request."} 2. 默认解析器设置为 'rest_framework.parsers.JSONParser' 3. 没有 parser_classes 作为视图属性。
    • 设置 parser_classes = (JSONParser,) 用于查看,但没有区别
    • 好的,从设置中删除 default_parser (JSON) 确实很神奇。深入研究框架,当设置默认解析器(JSON)并且内容类型为'multipart/form -数据'
    • 是的,我应该将您的答案标记为正确。但是为了记录,这里是我出错的地方。直到现在我还以为,settings.DEFAULT_PARSER_CLASSES 是在没有找到时设置默认解析器。现在我意识到,它应该包含您想要使用的所有可能的解析器。因为它使用这些设置作为最终列表(如果可用)。现在我将 JSON/Form/Multipart 设置为默认值,一切都很好。谢谢。默认有多种含义:)
    • 我在 DRF 3.3 上遇到了这个问题,这是因为我使用的是 django.test.TestCase 而不是 rest_framework.test.APITestCase。一旦我做出改变,问题就消失了。
    【解决方案2】:

    收到 415 错误,因为我使用了 django.test import Client 的实例而不是 rest_framework.test import APIClientAPIClient 将自动以正确的方式对数据进行编码。

    纯json请求:

    client = APIClient()
    client.post(url, format='json', data=json, headers=headers)
    client.put(url, format='json', data=json, headers=headers)
    

    创建/更新包括文件:

    client = APIClient()
    client.post(url, format='multipart', data=data, headers=headers)
    client.put(url, format='multipart', data=data, headers=headers)
    

    我花了很多时间处理这个 415 错误,所以我希望这对其他人有帮助。

    【讨论】:

      猜你喜欢
      • 2020-12-03
      • 1970-01-01
      • 2013-10-27
      • 2021-11-27
      • 1970-01-01
      • 2016-03-12
      • 2013-05-12
      • 2015-07-08
      • 1970-01-01
      相关资源
      最近更新 更多