2009-09-03 24 views
6

Tôi đang gửi yêu cầu AJAX đến chế độ xem Django có khả năng mất nhiều thời gian. Nó đi qua một số bước được xác định rõ ràng, tuy nhiên, vì vậy tôi muốn in các chỉ báo trạng thái cho người dùng để cho nó biết khi nào nó kết thúc làm một điều nào đó và đã chuyển sang bước tiếp theo.Django - phản ứng tuôn ra?

Nếu tôi đã sử dụng PHP nó có thể trông như thế này, bằng cách sử dụng chức năng flush:

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

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

Làm thế nào tôi sẽ đi về làm việc cùng với Django? Nhìn vào the documentation Tôi thấy rằng các đối tượng HttpResponse có một phương thức tuôn ra, nhưng tất cả nó phải nói là "Phương pháp này làm cho một cá thể HttpResponse là một đối tượng giống như tệp." - Tôi không chắc đó là điều tôi muốn. Tôi đang có một thời gian khó khăn bao quanh đầu của tôi như thế nào điều này có thể được thực hiện trong Django kể từ khi tôi phải trả lời phản ứng và không thực sự có một kiểm soát khi nội dung đi vào trình duyệt.

Trả lời

8

Hầu hết các máy chủ web (ví dụ: FCGI/SCGI) đều có bộ đệm của riêng chúng, các máy khách HTTP thực hiện riêng, v.v. Rất khó để thực sự xóa dữ liệu theo cách này và cho khách hàng thực sự nhận được dữ liệu, bởi vì nó không phải là một hoạt động điển hình.

Gần nhất với những gì bạn đang cố gắng làm là chuyển một trình vòng lặp tới HttpResponse và thực hiện công việc trong máy phát; một cái gì đó như thế này:

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

... nhưng điều này sẽ không nhất thiết phải tuôn ra. (Mã không được thử nghiệm, nhưng bạn có ý tưởng; xem http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators.)

Hầu hết cơ sở hạ tầng đơn giản là không mong đợi phản hồi từng phần. Ngay cả khi Django không phải là đệm, máy chủ front-end của bạn có thể được, và khách hàng có lẽ là, quá. Đó là lý do tại sao hầu hết mọi thứ sử dụng bản cập nhật kéo cho điều này: một giao diện riêng biệt để truy vấn trạng thái của một yêu cầu chạy dài.

(Tôi muốn có thể làm cập nhật đẩy đáng tin cậy cho các loại điều này, quá ...)

+0

Cảm ơn. Tôi đã thử máy phát điện nhưng đủ ngu ngốc tôi đã sinh ra các số nguyên trong thử nghiệm của mình và nó làm cho nó không hoạt động. Tôi có lẽ sẽ kết thúc không làm điều này ở tất cả, nhưng nó là tốt đẹp để biết nó ít nhất là làm việc, mặc dù với những hạn chế bạn đã đề cập. –

4

Tôi không chắc chắn bạn cần phải sử dụng flush() chức năng.

Yêu cầu AJAX của bạn chỉ cần chuyển đến chế độ xem django.

Nếu các bước của bạn có thể bị hỏng, hãy đơn giản và tạo chế độ xem cho từng bước. Bằng cách đó, một quy trình hoàn tất, bạn có thể cập nhật người dùng và bắt đầu yêu cầu tiếp theo qua AJAX.

views.py

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

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

Trong nhiều trường hợp, điều này không được mong muốn. Nếu toàn bộ hoạt động là một đơn vị, sau đó nó thêm sự chậm trễ không cần thiết giữa mỗi giai đoạn bắt đầu (chờ đợi cho khách hàng để kick nó đi); điều này là tồi tệ hơn nếu bạn muốn làm các cập nhật tốt hơn (ví dụ như phần trăm hoàn thành). Toàn bộ hoạt động có thể muốn được chạy trong một giao dịch cơ sở dữ liệu duy nhất; ngay cả khi nó không, bạn có thể muốn dọn dẹp nếu nó toàn bộ hoạt động không được hoàn thành, có nghĩa là bạn cũng cần một thời gian chờ để hủy bỏ nếu khách hàng biến mất. Tất nhiên, nó phụ thuộc vào những gì bạn đang làm. –

+0

Tôi đồng ý, nó phụ thuộc vào cấu trúc và kỳ vọng của kết quả. – monkut

+0

Tôi xem xét việc chia nhỏ nó, nhưng vì những lý do đã đề cập ở trên và sau đó một số tôi đã thực sự hy vọng để tránh nó. Tuy nhiên, tất cả các bước là độc lập 100%, nhưng không có giới hạn 2 yêu cầu hoạt động cho mỗi tên miền hoặc điều gì đó tương tự? –

Các vấn đề liên quan