Django: вернуть StreamingHttpResponse на существующей HTML-странице

Поскольку лучше иметь один вопрос для каждой проблемы, наберитесь терпения, если он похож на другую часть другой мой вопрос, относящийся к тому же проекту.

Ситуация:

У меня есть форма на html, в которой я могу установить число, и когда оно отправляется, это вызов views.stream_response, который передает значение в stream.py и возвращает StreamingHttpResponse и появляется «виртуальная» пустая страница браузера (/stream_response/), на которой я могу видеть прогрессивное число каждую секунду до m :

   1
   2
   3
   ..
   m

stream.py

import time

def streamx(m):
    lista = []
    x=0
    while len(lista) < m:      
        x = x + 1
        time.sleep(1)
        lista.append(x)
        yield "<div>%s</div>\n" % x 
        print(lista[-1])    
    return (x)

---ОБНОВЛЕНИЕ---

views.py

def stream_response(request):   
    test = InputNumeroForm()   
    if request.method == 'POST':
        test = InputNumeroForm(data=request.POST)
        if test.is_valid():
            m = test.cleaned_data['numero']     
            print (test)      
            print("m = ", m) 
            #resp = StreamingHttpResponse(stream_response_generator(m))
            resp = StreamingHttpResponse(stream.streamx(m))
            return resp               
        return render(request, 'homepage/provadata.html',{'user.username': request, 'test': test}, context_instance = RequestContext(request))

urls.py

...
url(r'^homepage/provadata/$', views.provadata),    
url(r'^stream_response/$', views.stream_response, name='stream_response'),
...

домашняя страница/provadata.html

<form  id="numero" action="/stream_response_bis/" method="POST">
    {% csrf_token %}
    {{test}}                                
    <input type="submit" value="to view" />
</form> 

//{{ris}} 

Я попытался выполнить ответ render_to, чтобы остаться на homepage/provadata.html и просмотреть прогрессивные списки, но stream.py не запускается, и я вижу только введенный номер m в командной строке.

Я попытался использовать ЭТО предложение в views.py

def stream_response_generator(m):    
    ris = stream.streamx(m) 
    yield loader.get_template('homepage/provadata.html').render(Context({'ris': ris}))

(добавляя {{ris}} в шаблон и
resp = StreamingHttpResponse(stream_response_generator(m)) в функцию stream_response), но я получаю на шаблоне:

<generator object streamx at 0x0000000004BEB870>

И в командной строке он печатает входное значение, но больше не передает параметр в stream.py.

Итак... Как я могу решить эту проблему?


person Trix    schedule 30.04.2015    source источник
comment
вы смотрели на этот ответ: stackoverflow.com/questions/2922874/   -  person ger.s.brett    schedule 30.04.2015
comment
@ ger.s.brett Да, но он указывает (как в моем случае) на физически не существующую HTML-страницу ... Я не знаю, как объяснить это яснее.   -  person Trix    schedule 30.04.2015
comment
если вы хотите использовать ajax - зачем вам вообще поток?   -  person ger.s.brett    schedule 01.05.2015
comment
Во многих ответах или комментариях я видел, что люди ссылаются на ajax... поэтому я попытался с ним, но я думаю, что для моей цели StreamHttpResponse является решением. Я новичок в программировании и, возможно, есть много вещей, которых я не знаю, поэтому я обратился сюда за помощью.   -  person Trix    schedule 04.05.2015
comment
Вы решили свой вопрос? Вам нужен правильный ответ?   -  person Charlesthk    schedule 16.05.2015
comment
Нет, еще не решил.   -  person Trix    schedule 18.05.2015
comment
stream.py неверен - есть синтаксическая ошибка (вы не можете вернуть значение в генераторе). Так что кажется, что вы не правильно опубликовали вопрос.   -  person Konstantin Svintsov    schedule 14.09.2015


Ответы (1)


Вы можете использовать StreamingHttpResponse, чтобы указать, что вы хотите передавать результаты обратно, и все промежуточное программное обеспечение, которое поставляется с django, знает об этом и действует соответственно, чтобы не буферизовать вывод вашего контента, а отправлять его прямо по линии.

Вы можете отключить промежуточное ПО ETAG с помощью декоратора условий. Это вернет ваш ответ для потоковой передачи через HTTP. Вы можете подтвердить это с помощью инструмента командной строки, такого как curl. Но этого, вероятно, будет недостаточно, чтобы ваш браузер отображал ответ во время его потоковой передачи. Чтобы побудить браузер показывать ответ во время его потоковой передачи, вы можете протолкнуть кучу пробелов вниз по каналу, чтобы заставить его буферы заполниться. Пример следующий:

from django.views.decorators.http import condition

@condition(etag_func=None)
def stream_response(request):
    resp = HttpResponse( stream_response_generator(), mimetype='text/html')
    return resp

def stream_response_generator():
    yield "<html><body>\n"
    for x in range(1,11):
        yield "<div>%s</div>\n" % x
        yield " " * 1024  # Encourage browser to render incrementally
        time.sleep(1)
    yield "</body></html>\n"
person sottany    schedule 20.11.2015