首页 > 解决方案 > 如何在django前端显示后端流数据

问题描述

我有一个 django 应用程序,它从客户端接收一个值并在后端执行一些进程,这个过程需要时间,我想向用户显示实时进程输出。
在我正在使用的后端subprocess.Popen,然后我正在使用yield返回流数据。并在views.pyStreamingHttpResponse()用来显示流数据的地方。
我的问题是,当进程开始时,实时结果显示在空白页面中,但我想在当前页面和终端窗口中显示实时数据。该过程完成后,我想向用户显示“下载”按钮,以将结果下载为 pdf。构建 PDF 文件和下载页面的所有内容都很完美,我的文件正在 /media 目录中。在我遇到问题之前,我这样做了,客户可以下载结果 pdf。但是现在,我想在应用程序中添加直播以显示该过程。\

这是我当前views.py在新的空白页面中运行完美的电流。

@login_required(login_url='/login/')
def dir_s(request):
    if request.method == 'GET':
        return render(request, 'app/dir_s.html', {'form':IpsForm()})

    elif request.method == 'POST':
        try:
            global ip, user_name, function_name
            form = IpsForm(request.POST)
            if form.is_valid():
                ip = form.cleaned_data.get('ip')
            function_name = dir_s.__name__
            user_name = request.user
            response = StreamingHttpResponse(
                dir_s.dir_script(ip, user_name, function_name)
            )  # dir_s.dir_script() will be return datas with yield command. the data is as a list and i'm using for loop to yield every line

            response['Content-Type'] = 'text/event-stream'
            return response

        except ValueError:
            return render(request, 'app/dashboard.html', {'form':IpsForm()}, {'error':'Bad data passed in. Try again.'})

    return render(request, 'app/download.html')


@login_required(login_url='/login/')
def download_file(request):
    filename = f"{function_name}-{ip}.pdf"
    # Define the full file path
    filepath = f"{BASE_DIR}/toolkit/media/toolkit/reports/{user_name}/{filename}"
    # Open the file for reading content
    if os.path.exists(filepath):
        # Set the return value of the HttpResponse
        response = HttpResponse(open(filepath, 'rb'))
    # Set the HTTP header for sending to browser
        response['Content-Disposition'] = "attachment; filename=%s" % filename
        return response
    # Return the response value
    else:
        raise HTTP404

这是我的dir_s.dir_script()

for line in process.stdout:
    #sys.stdout.write(str(line))
    output.append(line.decode('utf-8'))
    yield f"{line.decode('utf-8')}"
    time.sleep(0.5)

if check():
    convert_to_pdf(output, user_name, ip, function_name)

这是dir_s.html在白页中显示数据的模板部分:

<script>
    var eventsource = new EventSource("{% url 'dir_s'%}")
    eventsource.onopen = function(){
        console.log("Connection opened");
    }
    eventsource.onmessage = function () {
        console.log(e);
    }
    eventsource.onerror = function (){
        console.log('error:')
    }
</script>

这项工作将在return response部分结束。我想在 dir_s.html 中的 IpsForm() 下显示结果,并且我想在该过程完成后显示“下载”按钮。你能帮我怎么做吗?

标签: python-3.xdjango

解决方案


推荐阅读