【问题标题】:How to test mp3 upload in Django DRF, via PUT?如何通过 PUT 在 Django DRF 中测试 mp3 上传?
【发布时间】:2021-04-10 15:05:45
【问题描述】:

我尝试测试 mp3 修改(因此 PUT)。到目前为止,我有以下内容:

client = Client()
with open('my_modified_audio.mp3', 'rb') as fp:
    response = client.put(
            f"/resource/{resource_id}/",
            data={'audio': fp})

但是,我得到 response.status_code == 415,因为 DRF 的 ModelViewSet 中的序列化程序行
serializer = self.get_serializer(instance, data=request.data, partial=partial)
失败
rest_framework.exceptions.UnsupportedMediaType: Unsupported media type "application/octet-stream" in request.

我尝试设置format="multipart",将内容类型设置为json 或form-encoded,到目前为止没有任何帮助。 Resource 模型使用 FileField:

class Resource(models.Model):
    audio = models.FileField(upload_to='uploads')

我怎样才能使这个 put 请求工作?

【问题讨论】:

    标签: django django-rest-framework django-testing django-tests


    【解决方案1】:

    我认为以下方法会起作用:

    客户:

    import requests
    ...
    
    client = Client()
    files = [('audio': open('my_modified_audio.mp3', 'rb'))]
    url = f"/resource/{resource_id}/"
    
    # response = client.put(url, data=None, files=files)
    # You can test it using the `requests` instead of Client()
    response = requests.put(url, data=None, files=files)
    

    序列化器:

    class AudioSerializer(serializers.Serializer):
        """ AudioSerializer """
        audio = serializers.FileField(...)
    
        def create(self, validated_data):
            ...
    
        def update(self, instance, validated_data):
            ...
    

    观点:

    from rest_framework.generics import UpdateAPIView
    
    class AudioView(UpdateAPIView):
       ...
       parser_classes = (FormParser, MultiPartParser)
       serializer_class = AudioSerializer
       ...
    

    【讨论】:

    • 感谢您的努力,@athanasp,我试过了,它给了我错误 415。但是,您启发了我研究 django 的代码并最终找到了一个可行的解决方案。
    【解决方案2】:

    受@athansp 回答的启发,我比较了client.postclient.put 的源代码,结果发现put 的实现与post 略有不同,所以用put 提交文件的可行方法是:

    from django.test.client import MULTIPART_CONTENT, encode_multipart, BOUNDARY
    
    client = Client()
    with open('my_modified_audio.mp3', 'rb') as fp:
        response = client.put(
            f"/resource/{resource_id}/",
            data=encode_multipart(BOUNDARY, {
                'other_field': 'some other data',
                'audio': fp,
            }),
            content_type=MULTIPART_CONTENT
        )
    

    哈哈。

    【讨论】:

      猜你喜欢
      • 2021-01-27
      • 2011-08-09
      • 2017-11-17
      • 2012-03-03
      • 2018-10-23
      • 2017-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多