0

I'm making an AJAX call to a Django POST view. It's reading X files locally, and then sending back to the front-end (thanks to ajax), so the user can download them.

Everything is working fine on this part, but i'd like to have some sort of "intermediate response", which would tell Ajax each time the server reads one file.

That way, i could create a loading bar on the front end while the server is processing the request.

Is there any way i could do it, using ajax, or something else (anything would be fine, as long as i'd keep my ajax request somewhere).

Here is my code, quite simplified, so you can understand better what I'd like it to do:

Django:

def downloadFiles_API(request):
    if request.is_ajax and request.method == "POST":
        requested_files = json.loads(request.body)['files']
        for file in requested_files:
            # Handle file reading (this part works)
            # Here i'd like to tell the front end "File X has been loaded..." (for each file)
        # Zip-ing all files, and send it as response
        return FileResponse(myZipFile)

AJAX:

$.ajax({
        url: "/api/downloadFiles/",
        type: 'POST',
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify({
            "files" : filesThatTheUserWants,
        }),
        xhrFields:{
            responseType: 'blob'
        },
        success: function (response){
            // Download the file in response (this works)
        },
        // And what i'd like to add (it's NOT in my code):
        onProgress: function (intermediateResponse){
            console.log(intermediateReponse);
            // Would print "File X has been loaded..."
            // Each time a file is loaded on server side
        }

Note: I found some similar questions, but they are either too generic, or not explaining the ajax part (like these: Send intermediate messages during an Ajax call, or How to stream an HttpResponse with Django)

  • Everytime you would like to tell frontend that `file x has been loaded` or only one time? – Sunderam Dubey Apr 27 '22 at 08:23
  • Each time a file has been loaded, so multiple times. I'll edit to make it clearer. – Nicolas DUVOISIN Apr 27 '22 at 08:24
  • I think you can return `JsonResponse` every time inside the loop. – Sunderam Dubey Apr 27 '22 at 08:25
  • 1
    @SunderamDubey wouldn't it end the ajax block ? – Nicolas DUVOISIN Apr 27 '22 at 08:27
  • Can you edit your question with `dowloadfiles_API` full view, that what you are exactly doing inside the `loop`? – Sunderam Dubey Apr 27 '22 at 08:28
  • that's also the thing, it will end the block. – Sunderam Dubey Apr 27 '22 at 08:28
  • @SunderamDubey The loop part is quite complex in the real code, so i simplified it a lot here. To make it clear, let's say on each iteration, it reads one of the files asked by the user, and when every file has been read, they get zipped and sent to ajax. So what i'd like to do is to "notify" the front end each time one file has been read on server side. – Nicolas DUVOISIN Apr 27 '22 at 08:34
  • 1
    Hello @NicolasDUVOISIN you can't do this with ajax because your function will work in one request and response cycle eg. You'll send a ajax request and server will proccess that request and it will send you a response you can't intercept inbetween this cycle if try then it send another request. – Ankit Tiwari Apr 27 '22 at 09:25
  • 2
    @AnkitTiwari Thanks for the clarification. I'll edit the question a bit, maybe there's a work around with something else than Ajax ? Maybe Web Sockets ? – Nicolas DUVOISIN Apr 27 '22 at 09:30
  • 1
    One way you can do this is by using socket which will send a event from server and you can access that event in client side – Ankit Tiwari Apr 27 '22 at 09:31
  • @AnkitTiwari could you send an example that could work in my scenario ? Sounds like a good answer to me ! – Nicolas DUVOISIN Apr 27 '22 at 09:32
  • 1
    I'll suggest you to follow this doc [django-socketio](https://django-socketio.readthedocs.io/en/latest/) or you can use [django-channels](https://channels.readthedocs.io/en/stable/) – Ankit Tiwari Apr 27 '22 at 09:44
  • 1
    Yes, @AnkitTiwari it can be done through websockets and channels package. That's what I was thinking. – Sunderam Dubey Apr 27 '22 at 11:18

0 Answers0