2009-09-03 17 views
6

Wysyłam żądanie AJAX do widoku Django, które potencjalnie może zająć dużo czasu. Przechodzi jednak przez niektóre ściśle określone kroki, dlatego chciałbym wydrukować wskaźniki stanu, aby użytkownik wiedział, kiedy zakończy działanie i przejdzie do następnego.Django - odpowiedź na kolor?

Gdybym używał PHP może to wyglądać tak, używając flush funkcję:

do_something(); 
print 'Done doing something!'; 
flush(); 

do_something_else(); 
print 'Done doing something else!'; 
flush(); 

Jak bym go o to robi to samo z Django? Patrząc na the documentation widzę, że obiekty HttpResponse mają metodę flush, ale wszystko, co musi powiedzieć, to: "Ta metoda sprawia, że ​​instancja HttpResponse jest obiektem podobnym do pliku." - Nie jestem pewien, czy tego chcę. Ciężko jest mi zawinąć głowę, jak można to zrobić w Django, ponieważ muszę zwrócić odpowiedź i tak naprawdę nie mam kontroli nad tym, kiedy zawartość trafi do przeglądarki.

Odpowiedz

8

Większość serwerów internetowych (np. FCGI/SCGI) wykonuje własne buforowanie, klienci HTTP działają samodzielnie i tak dalej. Bardzo trudno jest uzyskać dane przepłukane w ten sposób, a klient faktycznie je odbierać, ponieważ nie jest to typowa operacja.

Najbliższy temu, co próbujesz zrobić, to przekazanie iteratora do HttpResponse i wykonanie pracy w generatorze; coś takiego:

def index(request): 
    def do_work(): 
     step_1() 
     yield "step 1 complete" 
     step_2() 
     yield "step 2 complete" 
     step_3() 
     yield "step 3 complete" 
    return HttpResponse(do_work()) 

... ale to nie będzie koniecznie równo. (Nie testowany kod, ale masz pomysł, zobacz http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators.)

Większość infrastruktury po prostu nie oczekuje częściowej odpowiedzi. Nawet jeśli Django nie buforuje, może to być serwer frontonu, a klient prawdopodobnie także. Dlatego większość rzeczy używa do tego aktualizacji ściągania: osobnego interfejsu do sprawdzania statusu długo działającego żądania.

(Chciałbym móc zrobić niezawodne aktualizacje dążyć do tego typu rzeczy, zbyt ...)

+0

Dzięki. Próbowałem generatorów, ale na tyle głupio, że wystawiałem na próbę liczby całkowite i sprawiło, że nie działało. Prawdopodobnie nie skończę tego, ale miło jest wiedzieć, że przynajmniej zadziałało, choć z ograniczeniami, o których wspomniałeś. –

4

Nie jestem pewien, trzeba użyć funkcji() kolor.

Twoje żądanie AJAX powinno po prostu przejść do widoku django.

Jeśli Twoje kroki można zepsuć, zachowaj prostotę i utwórz widok dla każdego kroku. W ten sposób jeden proces zakończy się, możesz zaktualizować użytkownika i rozpocząć następne żądanie za pośrednictwem AJAX.

views.py

def do_something(request): 
    # stuff here 
    return HttpResponse() 

def do_something_else(request): 
    # more stuff 
    return HttpResponse() 
+0

W wielu przypadkach nie jest to jednak pożądane. Jeśli cała operacja jest jednostką, to dodaje niepotrzebne opóźnienie między każdym rozpoczęciem fazy (oczekiwanie, aż klient ją wyrzuci); to jest gorsze, jeśli chcesz wykonać drobniejsze aktualizacje (np. procent ukończono). Cała operacja może być uruchamiana w pojedynczej transakcji bazy danych; nawet jeśli nie, możesz oczyścić, jeśli cała operacja nie zostanie zakończona, co oznacza, że ​​musisz także przerwać działanie, jeśli klient zniknie. Oczywiście zależy to od tego, co robisz. –

+0

Zgadzam się, zależy to od struktury i oczekiwań wyniku. – monkut

+0

Zastanawiałem się nad podzieleniem go, ale z powodów wymienionych powyżej, a następnie niektóre, które naprawdę miałem nadzieję, aby tego uniknąć. Wszystkie kroki są jednak w 100% niezależne, ale czy nie ma 2 aktywnych limitów na domenę lub coś podobnego? –