1

I have a dynamically created table with data from a django model. This table is displaying additional information about each data_element.

In the last column there should either

  • be a button displayed for each row, which will run the script with additional keywords from that specific data_element, without reloading or freezing the page.
  • If the script is still running (can take hours) there should be progress icon displayed and
  • if the script has already finished, there should be a button displayed, redirecting to an results.html

How can I program that with django? Currently I am executing a script manually, but for that I am redirecting to another template with the args to parse and when the script is executed (with call_command('my_script', *args) the page freezes until the script ends.

<form action="{% url 'calculate' element_id %}">
  <input class="btn btn-primary-custom" id="submit" type="submit" value="run script">
</form>

I tried to insert the code from this post: Django button ajax click

But when I click on that button, nothing happens. What do I have to do, to create that table?

EDIT the function for my button currently looks like this:

$(document).ready(function(){
    $('.calculate-btn').bind('click', function(){
        function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }

    var btn-data= $(this).attr('btn-data');
    var csrftoken = getCookie('csrftoken');
        $.ajax({
        type: 'POST',
        url : "/run/",
        dataType: "html",
        data : {'csrfmiddlewaretoken': csrftoken, 'btn-data':btn-data},
        success: function(data, status, xhr){
            console.log("SUCCESS")
        },
        error: function(data, status, xhr){
            console.log("ERROR")
        }
        });

        return false;
    });
});

and my view gets called from a button click:

 <input id="{{item.id}}" class='calculate-btn' name="update_log" type="button" value="Run Script" btn-data={{ item.id }}>

How can I now dynamically change the button, while the script is still running?

Community
  • 1
  • 1
Ali
  • 761
  • 1
  • 5
  • 24

2 Answers2

1

You will need a way to launch async tasks, and a way to get the task status, and then add quite some js/ajax code to launch the task and update your table accordingly.

For the first two parts, the canonical solution is celery.

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
0

Another, less recommended way to do that (less recommended, but probably easier to setup than celery) is to simply spawn a child, detached process which will complete the job in the background and store the status and results somewhere (e.g. in your database or in a memory storage like redis).

The main disadventage is that you lose control of what is happening in the child process. Depending on your project - if you don't care about the process control - it may turn out to be better solution.

Community
  • 1
  • 1
niespodd
  • 396
  • 3
  • 5
  • I don't need to control the process as long as the user can't start the script again, while it is already running. How can I spawn a child for that specific row, without leaving the page? – Ali Nov 07 '16 at 15:37
  • Okay, I run my script with `subprocess.Popen(['python','my_script.py',args])`. I can check within that python script by using `.pool()` if it is finished, but how do I check that dynamically on the website, while the user is browsing around? – Ali Nov 08 '16 at 16:27