Search code examples
djangodjango-rest-frameworkdjango-testingdjango-tests

How to test mp3 upload in Django DRF, via PUT?


I try to test mp3 modification (hence PUT). I have the following so far:

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

However, I get response.status_code == 415 because the serializer line in DRF's ModelViewSet
serializer = self.get_serializer(instance, data=request.data, partial=partial).
fails with
rest_framework.exceptions.UnsupportedMediaType: Unsupported media type "application/octet-stream" in request.

I have tried setting format="multipart", setting the content type to json or form-encoded, nothing helped so far. The Resource model uses FileField:

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

How can I make this put request work?


Solution

  • Inspired by @athansp's answer, I compared the source code of client.post and client.put and it turns out, put's implementation slightly differs from post, so a workable way of submitting files with put is:

    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
        )
    

    Lol.