3

I would like to build with django-celery a web-server that:

  1. Accepts data from user on the page /input/
  2. Starts a Celery task to process them
  3. Redirects to the page /wait/, where user waits until the processing is completed
  4. When the task is completed, automatically redirects to the page /result/

Currently I got stuck with the code (simplified):

views.py:

def input(request):
    # Read form data to 'parameters'
    task = process_user_input.delay(parameters)
    response = HttpResponseRedirect("/wait")
    response.session['task'] = task
    return response

def wait(request):
    task = request.session.get('task', None)
    while task.state not in ('SUCCESS', 'FAILURE'):
        time.sleep(0.1)
    return HttpResponseRedirect("/result")

def result(request):
    # 

urls.py:

urlpatterns = patterns('',
    url(r'^input/$', views.input, name = 'input'),
    url(r'^wait/$', views.wait, name = 'wait'),
    url(r'^result/$', views.result, name = 'result'),
)

This, however, does not work, as 'HttpResponseRedirect' object has no attribute 'session'. I also tried to use render function, but it only loads corresponding template without calling the view function.

Can someone help me to fix the code so that it fulfils my goal?

3
  • how could you pass the result of the middle processing? I am also stuck in the similar situation. input -> POST -> wait -> processing -> result. Your answer is helpful but it doesn't show how I can use the result of celery task when redirecting to the result page. Commented Aug 15, 2017 at 11:09
  • This is a simplified version of the code. In reality, you should of course save the results in the database (e.g., MySQL; celery will do this for you with the session object), pass the session id while redirecting (e.g., return redirect('some-view-name', id=1234; alternatively, you can use cookies for this), and extract the required information from the database in the results view. Commented Aug 15, 2017 at 12:45
  • Thanks. I'll use database or file as a medium. Commented Aug 15, 2017 at 12:48

1 Answer 1

1

After some research I came to conclusion I came to conclusion that the required functionality is not provided by django, as one cannot cannot render pages asynchronously (and, as a result, cannot render and redirect at the same time). Therefore, I decided to get rid of the /wait/ page. My views.py now looks like this:

from my_app.forms import InputForm
from mysite.tasks import process_user_input

def input(request):
    form = InputForm()
    # Read form data to 'parameters'
    task = process_user_input.delay(parameters)
    while task.state not in ('SUCCESS', 'FAILURE'):
        time.sleep(0.1)
    if task.failed():
        # Insert error message and return to the input form
        render(request, 'my_app/input.html', {'form': form})
    return HttpResponseRedirect("/result")

def result(request):
    # 

The waiting message I had to implement using Javascript with jQuery in input.html:

<div id="form_container">
    <!--The form (with id="input_form") is here-->
</div>
<div id="hidden_section" style="display: none;">
    <!--The please-wait-message is here-->
</div>

<script>
$(document).ready(function () {
    $("#input_form").submit(function () {
        $("#form_container").attr("style", "display: none");
        $("#hidden_section").attr("style", "display: block");
        return true;
    });
});
</script>

As a result, after submitting the form, a user remains on the /input/ page, but is seeing the please-wait-message until the task is completed or an error occurs.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.