1

I have an external python program, named c.py, which "counts" up to 20 seconds. I call it from my Django app views.py and in the html page I have a button to start it. It's ok (= in Eclipse I can see that c.py prints 0,1,2,3,...20 when I press the button on the webpage) but I would like that the button changes from "GO" to "WAIT" during c.py process (or I would like to perform a waiting page during the counting or also a pop-up).

c.py

import time

def prova(z):
    z = 0
    while z < 20:
        time.sleep(1)
        z = z + 1
        print(z)

views.py

    from django.shortcuts import render_to_response
    #etc.

    import c


def home_user(request):
    return render_to_response('homepage/home.html',{'user.username':request}, context_instance = RequestContext(request))

def conta(request):
    c.prova(0)
    return redirect(home_user)

where in homepage.html I have the "GO" button that I would like to change in "WAIT" if the function conta is running.

urls.py

        urlpatterns =patterns('',
    url(r'^homepage/home/$', views.home_user, name='home'),
    #etc.
    url(r'^conta', views.conta, name='conta'),


)

home.html

{% if c.alive %}
<a href="" class="btn btn-danger" role="button">WAIT</a>
{% else %}
<a href="/conta/" class="btn btn-primary" role="button">GO</a>
{% endif %}

I don't put the whole code.. I hope this is sufficient to understand my trouble. I also see at How to create a waiting page in Django but I would start with something simpler.

Up to now when I start c.py I see that my web page is loading something (=it is "counting") but my button does not change and, after c.py execution, I return to 127.0.0.1:8000/homepage/home/ page. Is the problem in html or in my function definition or both?

UPDATE

I try to simplify the question: I found this script...

    <button onclick="myFunction()">Try it</button>

<p id="demo"></p>

<script>
function myFunction() {
    var text = "";
    var i = 0;
    while (i < 10) {
        text += "<br>The number is " + i;
        i++;
    }
    document.getElementById("demo").innerHTML = text;
}
</script>

I would like to "import" my conta() function in while instead of the cicle with i++

i.e. I would like to have a similar thing: while conta() is running, appear something like

Waiting..

and when it stop i return to my home page.. I don't know how "put" conta() in the script.. is this possible? Am I a dreamer? :)
Community
  • 1
  • 1
Trix
  • 587
  • 1
  • 6
  • 27

2 Answers2

1

You're trying to check a server-side value on the client, but the problem is that the if c.alive statement only gets evaluated when your view is rendered - not as the status of c changes.

You would need to be able to report back the status of c to the client via ajax long polling or WebSockets, or, if you don't care about the incremental status of c and just want to change the text of the link, you'll need to use JavaScript to set the value when the click event of the link fires:

// assuming jQuery for brevity...

$(document).ready(function() {

    // avoid hard-coding urls...
    var yourApp = {
        contaUrl: "{% url 'conta' %}"
    };

    $('#btnGo').click(function(e) {
        e.preventDefault();  // prevent the link from navigating

        // set css classes and text of button
        $(this)
            .removeClass('btn-primary')
            .addClass('btn-danger')
            .text('WAIT');

        $.get(yourApp.contaUrl, function(json) {
             window.top = json.redirect;
        });
    });
});

but... your conta function will need to return a JsonResponse instead of an HttpResponse in order to do the redirect on the client-side:

from django.core.urlresolvers import reverse
from django.http import JsonResponse

def conta(request):
    c.prova(0)
    redirect = reverse('name_of_home_user_view')
    return JsonResponse({'redirect': redirect})
Brandon Taylor
  • 33,823
  • 15
  • 104
  • 144
  • At the moment it is very obscure for me... where can I study these arguments? Have you some link to suggest me, please? – Trix Mar 04 '15 at 08:11
  • No, not really. This is a fairly basic concept. You have a process executing on the server-side, which your template knows nothing about, unless it communicates with the server-side through Ajax. – Brandon Taylor Mar 04 '15 at 11:21
  • Ok, I understand the concept. I was referring to the jquery code syntax that I don't know yet. – Trix Mar 04 '15 at 11:42
  • Ah, that's easy - jquery.com :) – Brandon Taylor Mar 04 '15 at 11:45
  • Well, you need to add a name parameter to your home url pattern, include the JavaScript on the home page, add an id parameter to the link, refactor the the HTML... lots of things. My example was just to get you going in the right direction. – Brandon Taylor Mar 04 '15 at 14:12
  • Update: How I have to change urls.py and home.html? At the moment nothing it is changed except for the fact that I do not return to 127.0.0.1:8000/homepage/home/ but to 127.0.0.1:8000/conta in which only *{"redirect": "/homepage/home/"}* is displayed. I'm sorry but it's the first time for me with jquery and django, so I do not know what (and how) I have to do. – Trix Mar 04 '15 at 14:14
  • If I don't use JS, *prova()* runs (I see it from eclipse) while if I use JS, the button changes but the function *prova()* does **not run**. Maybe I misunderstood what *redirect = reverse('name_of_home_user_view') return JsonResponse({'redirect': redirect})* means – Trix Mar 16 '15 at 16:38
  • That is so that you don't have to hard-code the url for the view you want to redirect to. – Brandon Taylor Mar 16 '15 at 16:47
  • It (almost) works with *'/conta/'* instead of *"{% url 'conta' %}"*, *'almost'* because the button does not go back as *Class('btn-primary')*. – Trix Mar 17 '15 at 14:30
  • Hmm. I would have to write it out first-hand to see exactly what the issue is, but hopefully you're at least in a spot where you can work now :) – Brandon Taylor Mar 17 '15 at 14:34
1

I post my working solution. Thanks to @Brandon for the useful answer.

in conta.js some changes:

$(document).ready(function() {

    // avoid hard-coding urls...
    var yourApp = {
        contaUrl: "/conta/"
    };


    $('#btnGo').click(function(e) {
        e.preventDefault();  
        // set css classes and text of button
        $(this)
            .removeClass('btn-primary')
            .addClass('btn-danger disabled') // with *disabled* I'm sure that the button is not clickable
            .text('WAIT');



        $.get(yourApp.contaUrl, function(json) {     
             alert("I have finished counting");                    
             parent.window.location.reload(true);               


        });
    });
});

in views.py

def conta(request):
    c.prova(0)
    redirect = reverse('home')                  
    return JsonResponse({'redirect': redirect})
Trix
  • 587
  • 1
  • 6
  • 27