Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to post and retrieve blob with Django

I have a blob. It's an image that I resized using a <canvas>. I've verified that the data is correct by converting it to a url to test it as per the MDN guide. So far so good. Now, I'd like to post it to my Django server (along with some other inputs).

So I do this:

var fd = new FormData(form);
canvas.toBlob( function(blob) {
  fd.set("image0", blob, "image0.jpg");
}, "image/jpeg", 0.7);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/ajax-upload/', true);
xhr.setRequestHeader("X-CSRFToken", csrftoken);
xhr.send(fd);

I inspect the POST message with the network inspector console. My blob is confirmed as sent with the POST request and I can see the binary data send as the "image0" field.

-----------------------------1773139883502878911993383390
Content-Disposition: form-data; name="image0"; filename="blob"
Content-Type: image/png

So I handle the POST request with this view, accessible at url /ajax-upload/:

def ajax_upload(request):
    if request.method == 'POST':
        print(request.POST.urlencode())

This gives me nothing. Once I find out where my blob went, how can I turn it into an Image? Something like img = Image.open(request.POST["image0"])?

like image 283
Escher Avatar asked Oct 31 '22 08:10

Escher


2 Answers

A blob is binary data, so you can find it in the request.body in Django. Its Bytes encoded (not Unicode).

HttpRequest.body The raw HTTP request body as a bytestring. This is useful for processing data in different ways than conventional HTML forms: binary images, XML payload etc.

like image 164
C14L Avatar answered Nov 09 '22 11:11

C14L


It is easy, you may just... read it:

#views.py

class Upload(View):

    def get(self, request):     
        # Sanity check if your server is up and running, reply to HTTP request
        print('Got get request...') # log it for debug purpose
        return HttpResponse('<H1>POST endpoint.</H1>', status=200)        

    def post(self, request):
        ## here I used it with plupload.js for chunked upload, but it works anyway
        ... ## here you do something with headers
        file_name = request.POST['name'] # or some 'file_name_with_path.bin'
        chunk_num = int(request.POST['chunk']) # get it from the request 
        
        ## Finally, you know this is multipart and headers are okay, let save it. 
        uploaded_file = request.FILES['file'] # data from request
        if chunk_num == 0: 
            ## The very first chunk — create/overwrite binary file
            with open(file_name, 'wb+') as f:
                f.write(uploaded_file.read()) # so, just read it from the request          
        else:
            ## Next chunks — append the file!
            with open(file_name, 'ab') as f:
                f.write(uploaded_file.read())

In your case:

def ajax_upload(request):
    ...
    img = Image.open(request.POST["file"].read())
    ...
    return HttpResponse('{"Status":"OK"}', status=200)

PS: I am aware, the question is a bit old, but I had the same issue and solved it in no time, but I struggled to find a solution by search initially.

like image 28
Constantine Kurbatov Avatar answered Nov 09 '22 09:11

Constantine Kurbatov