如何通过PUT测试Django DRF中的mp3上传



我尝试测试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或表单编码,到目前为止没有任何帮助。资源模型使用FileField:

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

我如何使此put请求生效?

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

客户:

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
...

受@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
)

哈哈。

最新更新