Django:在现有的 html 页面上返回一个 StreamingHttpResponse [英] Django: return a StreamingHttpResponse on an existing html page

查看:60
本文介绍了Django:在现有的 html 页面上返回一个 StreamingHttpResponse的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于每个问题最好有一个问题,如果与另一个我的问题与同一个项目相关.

情况:

我有一个 html 表单,我可以在其中设置一个数字,当它提交时,调用 views.stream_response 将值传递给 stream.py它返回一个 StreamingHttpResponse 并出现虚拟"空白浏览器页面 (/stream_response/),我可以在其中每秒看到一个渐进式数字,最高可达 m:

<代码> 123..米

stream.py

导入时间定义流x(米):列表 = []x=0而 len(lista) <米:x = x + 1时间.sleep(1)lista.append(x)产量 "

%s

" % x打印(列表 [-1])回报 (x)

---更新---

views.py

def stream_response(request):测试 = InputNumeroForm()如果 request.method == 'POST':测试 = InputNumeroForm(data=request.POST)如果 test.is_valid():m = test.cleaned_data['numero']打印(测试)打印(米=",米)#resp = StreamingHttpResponse(stream_response_generator(m))resp = StreamingHttpResponse(stream.streamx(m))返回响应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'),...

homepage/provadata.html

{% csrf_token %}{{测试}}<input type="submit" value="查看"/></表单>//{{ris}}

我试图做一个 render_to 响应以留在 homepage/provadata.html 并查看渐进式列表,但 stream.py 没有启动,我只能看到命令行上输入的数字 m.

我在 views.pyTHIS 建议>

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

(将 {{ris}} 添加到模板和
resp = StreamingHttpResponse(stream_response_generator(m))stream_response 函数中)但我在模板上获得:

并在命令行上打印输入值,但不再将参数传递给 stream.py.

那么.. 我该如何解决这个问题?

解决方案

你可以使用 StreamingHttpResponse 来表明你想将结果流回内容输出,但直接发送.

您可以使用条件装饰器禁用 ETAG 中间件.这将使您的响应通过 HTTP 流回.您可以使用 curl 等命令行工具确认这一点.但这可能不足以让您的浏览器在流式传输时显示响应.为了鼓励浏览器在响应流时显示响应,您可以将一堆空格向下推入管道以强制填充其缓冲区.示例如下:

from django.views.decorators.http 导入条件@condition(etag_func=None)定义流响应(请求):resp = HttpResponse(stream_response_generator(), mimetype='text/html')返回响应def stream_response_generator():产量 "
"对于范围内的 x(1,11):产量 "

%s

" % xyield " " * 1024 # 鼓励浏览器增量渲染时间.sleep(1)产生</body></html> "

Since it is better to have a single question for each issue, be patient if is similar to another part of another my question related to the same project.

The situation:

I have a form on html in which I can set a number and when it is submitted, it is call views.stream_response which pass the value to stream.py and it returns a StreamingHttpResponse and "virtual" blank browser page appears (/stream_response/) in which I can see a progressive number every second up to 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>
" % x 
        print(lista[-1])    
    return (x)

---UPDATE---

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'),
...

homepage/provadata.html

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

//{{ris}} 

I tried to do a render_to response to stay on homepage/provadata.html and to see the progressive lists but stream.py does not starts and I can see only the input number m on the command line.

I tried with THIS suggestion in views.py

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

(adding {{ris}} to template and
resp = StreamingHttpResponse(stream_response_generator(m)) in stream_response function) but I obtain on the template:

<generator object streamx at 0x0000000004BEB870>

And on command line it prints the input value but it not pass anymore the parameter to stream.py.

So.. How can I solve this issue?

解决方案

You can use the StreamingHttpResponse to indicate that you want to stream results back and all the middleware that ships with django is aware of this and acts accordingly to not buffer your content output but send it straight down the line.

You can disable the ETAG middleware using the condition decorator. That will get your response to stream back over HTTP. You can confirm this with a command-line tool like curl. But it probably won't be enough to get your browser to show the response as it streams. To encourage the browser to show the response as it streams, you can push a bunch of whitespace down the pipe to force its buffers to fill. Example follows:

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>
"
    for x in range(1,11):
        yield "<div>%s</div>
" % x
        yield " " * 1024  # Encourage browser to render incrementally
        time.sleep(1)
    yield "</body></html>
"

这篇关于Django:在现有的 html 页面上返回一个 StreamingHttpResponse的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆