-1

I have created a custom command which takes a positional and a named optional argument. It does many checks, downloads a file, unzips it and populates the database with the unzipped data.

To make the things more convenient for the users I created a simple form and created a view:

from django.views.generic.edit import FormView
from django.core import management

from .forms import DownloadForm

class DownloadFormView(FormView):
    template_name = 'frontend/download.html'
    form_class = DownloadForm
    success_url = '.'

    def form_valid(self, form):
        country = form.cleaned_data['country'][:3]
        levels = int(form.cleaned_data['country'][-1:])
        management.call_command('download_shapefile', country, levels=levels)
        return super(DownloadView, self).form_valid(form)

That works fine and now I want to provide feedback to the user, as the command might run for a while.

Is there any possibility to redirect the command output (or make it available) to the template and display it in the browser?

In my command I use:

self.stdout.write(self.style.SUCCESS('some success message'))
self.stdout.write(self.style.WARNING('some warning message'))

to output messages and don't print directly with the print method.

cezar
  • 11,616
  • 6
  • 48
  • 84
  • Sounds like you need to read up on how an API works, and perhaps look into django rest framework. There's not going to be an easy 1 line way to provide a command output to a template in a browser. Your browser probably will need to hit an API at a given interval to see if the response is ready. Another option is to look into channels. – DataSwede Jan 18 '18 at 17:13
  • @DataSwede I use Django REST Framework a lot, but I don't think it is the right tool for this task. Thank you for mentioning the `Channels`. That might offer something. I'll have a look at it. – cezar Feb 26 '18 at 13:53

1 Answers1

-1

You can make your task through Ajax and just lock the screen until the server returns a response. But this is a bad practice. The best solution would be to use Celery (or something like that). This is a distributed task queue. Your data will be written to the database after execution. Until that time, temporary results will be stored in the NoSQL. In this case, this is called a broker. After that, you can use the advice given above. You just ask the server if the answer is ready. If so, you can return it and show it to the user. Thus, the load on the server will be significantly reduced.

Nuchimik
  • 199
  • 7
  • Thank you for your answer. I know Celery, but I'm not really sure that it is the right tool. Using extra storage like NoSQL seems to me like an overkill. My main problem is to get read access to the Standard Output and after that make the contents available to a view. – cezar Feb 26 '18 at 13:56