2009-09-03 46 views
6

我正在向一個Django視圖發送一個AJAX請求,這可能需要很長時間。但是,它經歷了一些明確的步驟,因此我想打印狀態指示符給用戶,讓它知道什麼時候完成了某件事情,然後轉移到下一個。Django - 刷新響應?

如果我是用PHP它可能是這樣的,使用flush功能:

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

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

我怎麼會去這樣做同樣的Django的?看看the documentation我看到HttpResponse對象有一個flush方法,但是它只能說「這個方法使HttpResponse實例成爲一個文件類對象。」 - 我不確定那是我想要的。由於我必須返回響應,並且不能真正控制內容何時進入瀏覽器,所以我很難在Django中完成這個工作。

回答

8

大多數網絡服務器(例如FCGI/SCGI)自己做緩衝,HTTP客戶端自己做,等等。以這種方式實際清除數據並讓客戶實際接收數據是非常困難的,因爲這不是一種典型的操作。

最接近你想要做的是將一個迭代器傳遞給HttpResponse,並在一個生成器中完成工作;是這樣的:

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()) 

...但是這不會一定齊平。 (未經測試的代碼,但您明白了;請參閱http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators。)

大多數基礎架構根本沒有預期到零碎的響應。即使Django沒有緩衝,您的前端服務器可能也是,客戶端也可能是。這就是爲什麼大多數情況下使用拉更新的原因:一個單獨的界面來查詢長時間運行的請求的狀態。

(我希望能爲這種事做可靠推送更新,太...)

+0

謝謝。我曾嘗試過發生器,但是很愚蠢,我在測試中發現了整數,並且使其無法工作。我可能最終不會這樣做,但很高興知道它至少可以工作,儘管有你提到的限制。 – 2009-09-03 03:11:29

4

我不知道你需要使用的flush()函數。

您的AJAX請求應該轉到django視圖。

如果您的步驟可以細分,請保持簡單併爲每個步驟創建一個視圖。 這樣一個過程完成後,您可以更新用戶並通過AJAX啓動下一個請求。

views.py

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

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

儘管如此,在很多情況下這不是想要的。如果整個操作是一個單位,那麼它會在每個階段開始之間增加不必要的延遲(等待客戶端啓動);如果你想做更好的更新(比如完成百分比),情況會更糟糕。整個操作可能希望在單個數據庫事務中運行;即使沒有,也可能希望清理整個操作未完成,這意味着如果客戶端消失,還需要暫停超時。當然,這取決於你在做什麼。 – 2009-09-03 02:52:25

+0

我同意,這取決於結果的結構和期望。 – monkut 2009-09-03 03:05:47

+0

我曾考慮將其拆分,但出於上述原因,然後我真的希望避免它。但是,所有這些步驟都是100%獨立的,但是沒有每個域的2個活動請求限制或類似的限制? – 2009-09-03 03:10:20