Skip to content
Advertisement

Django request.FILES gets name, filename but not file (blob)

I’m trying to send an audiofile via a POST request to the server (aws, ec2) and I’m using Django, but my request.FILES doesn’t receive the blob file, but it DOES receive the key and the filename. Everything worked fine when I ran this on localhost.

How can I get the file?

I’m enabling my website on chrome://flags/#unsafely-treat-insecure-origin-as-secure, so that I can access the microphone.

Using RecorderJs to generate a Blob object containing the recorded audio in WAV format.

Main.js

rec.exportWAV(function(blob){
...
var fd = new FormData();
fd.append('text', speech);
fd.append('audio', blob, 'test.wav');
$.ajax({
 type: 'POST',
 enctype: 'multipart/form-data',
 url: url,
 data: fd,
 processData: false,
 contentType: false,
 success: function(response) {
  console.log(response);
 }
})
...

speech is String,

blob in console is Blob {size: 221228, type: “audio/wav”}, so it does exist.

Views.py:

@csrf_exempt
def get_blob(request):
    thislist = []
    for key in request.POST:
       thislist.append(request.POST.get(key))
    for key in request.FILES:
       thislist.append(request.FILES.get(key).name)

    json_stuff = json.dumps({"check": thislist})
    return HttpResponse(json_stuff, content_type="application/json")

I’ve tried with and without enctype, doesn’t make a difference. I’ve tried setting contentType to multipart/form-data, doesn’t make a difference.

The formdata seems to be sent correctly, because I can get the speech correctly (request.POST).

And I can get the key from request.FILES (‘audio’), and get the filename (‘test.wav’).

If I try request.FILES['audio'].read(), it says MultiValueDictError.

If I try request.FILES.get('audio').read() it says AttributeError, ‘NoneType’ object has no attribute ‘read’.

When I print request.POST I do get the dictionary with ‘text’: whatever text I’ve spoken.

When I print request.FILES I get an empty dictionary even though I can get the key and filename through for key in request.FILES: and request.FILES['audio'].filename.

Does anyone know what’s going on and/or can help me with the problem?

Advertisement

Answer

You may use read() method for it:

@csrf_exempt ## it doesn't work for post requests in later Django versions, so you need to disable it in another way or add a token to all post requests
 def get_blob(request):
    thislist = []
    for key in request.POST:
       thislist.append(request.POST.get(key))
    for key in request.FILES:
       thislist.append(request.FILES.get(key).name)
    # I am not sure that "name" exists in the request — you may use any filename, although the following works with multipart requests.
    with open(request.FILES["name"],"wb+") as f:
       f.write(request.FILES['file'].read())
    json_stuff = json.dumps({"check": thislist})
    return HttpResponse(json_stuff, content_type="application/json")

By the way, @csrf_exempt — doesn’t work for post requests in later Django versions, as a token is checked before your view is even called. So, you may need to disable CSRF middleware or just add a correct ‘X-CSRFToken’ token to all requests.

Advertisement