Как показать данные потока бэкенда во фронтенде в django
У меня есть приложение django, которое получает значение от клиента и выполняет некоторые процессы в бэкенде, и этот процесс занимает время, и я хочу показать пользователю живой результат процесса.
В бэкенде я использую subprocess.Popen
и затем я использую yield
для возврата данных потока. и в views.py
я использую StreamingHttpResponse()
для показа данных потока.
Моя проблема в том, что когда процесс запускается, результаты в реальном времени показываются на пустой странице, но я хочу показать данные в реальном времени на текущей странице и в окне терминала. И после завершения процесса я хочу показать кнопку Download пользователю, чтобы скачать результат в формате 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>
<<<Я хочу показать результат под IpsForm() в dir_s.html и хочу показать кнопку Download после завершения процесса. помогите, пожалуйста, как я могу это сделать?