服务器上不存在文件时不显示按钮 - 使用 Flask

是否可以仅在我的 Flask 应用程序创建文件后才显示下载按钮?使用 PHP,它可能是这样的:


<style>

.hidden{ display:none;}

</style>


<?php

if(!file_exists("path") ){ $class = "hidden" }

  echo "<button type=\"submit\" onclick=\"window.open(\'file.txt\')\">Download!</button>";

?>

我尝试直接在 HTML 文件中使用 Python 代码:


{% if os.path.isfile('file.txt') %}

    <button type="submit" onclick="window.open('file.txt')">Download!</button>

{% else %}

    <button type="submit" class="hidden" onclick="window.open('file.doc')">Download!</button>

{% endif %}

但出现错误:


jinja2.exceptions.UndefinedError: 'os' is undefined

更新

@furas 回复后的完整代码。代码应该做什么:

  1. 创建一个新线程,该线程将写入文件。

  2. 模板已呈现,并带有隐藏的下载按钮。

  3. 文件已创建

  4. 下载按钮自动可见 - 因为现在文件存在。

然而,在下面的代码中,该按钮在文件写入后保持隐藏状态。仅当创建文件后重新加载页面时,该按钮才会显示。

app.py

from flask import Flask, render_template

import threading

import time

import os

global exporting_threads



class ExportingThread(threading.Thread):


    def run(self):

        time.sleep(1)

        

        file = open("file.txt", "w") 

        file.close()



app = Flask(__name__)

app.debug = True



@app.route('/')

def index():

    exporting_threads = ExportingThread()

    exporting_threads.start()


    return render_template('index.html', file_exist = os.path.isfile('file.txt'))


if __name__ == '__main__':

    app.run()

index.html,位于“templates”文件夹内。


<!DOCTYPE html>

<html>

<head>

    <style>

    .hidden{ display:none;}

    </style>

</head>

<body>

    {% if file_exist %}

        <button type="submit" onclick="window.open('file.doc')">Download!</button>

    {% else %}

        <button type="submit" class="hidden" onclick="window.open('file.doc')">Download!</button>

    {% endif %}


</body>

</html>


小怪兽爱吃肉
浏览 96回答 1
1回答

绝地无双

PHP将代码与 HTML 混合在一起会造成大混乱。但 Flask 试图将其分开。在渲染模板之前检查文件是否存在于代码中并仅将结果发送到模板 - 即。&nbsp;return render_string(...., file_exist=os.path.isfile('file.txt'))并在模板中&nbsp;{% if file_exist %}&nbsp;编辑:通常文件位于子文件夹中,您应该使用&nbsp;os.path.isfile('subfolder/file.txt')甚至&nbsp;os.path.isfile('/full/path/to/file.txt')编辑:问题比较复杂。服务器需要更长的时间在单独的线程中创建文件,因此当服务器检查时该文件还不存在isfile()。它需要 JavaScript 和 AJAX,它将定期向其他功能(即/check)发送请求,并且它会True从.Falseisfile()使用纯 JavaScript 的最小工作示例,XMLHttpRequest但您可以尝试fetch()使用库来编写它jQueryfrom flask import Flask, render_template_stringimport threadingimport timeimport os# delete only for test code#if os.path.isfile('file.txt'):#&nbsp; &nbsp; os.unlink("file.txt")class ExportingThread(threading.Thread):&nbsp; &nbsp; def run(self):&nbsp; &nbsp; &nbsp; &nbsp; time.sleep(5)&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; file = open("file.txt", "w")&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; file.close()app = Flask(__name__)app.debug = True@app.route('/')def index():&nbsp; &nbsp; exporting_threads = ExportingThread()&nbsp; &nbsp; exporting_threads.start()&nbsp; &nbsp; return render_template_string('''<!DOCTYPE html><html><head>&nbsp; &nbsp; <style>&nbsp; &nbsp; .hidden {display:none;}&nbsp; &nbsp; </style></head><body>&nbsp; &nbsp; <button id="button" type="submit" class="hidden" onclick="window.open('file.doc')">Download!</button>&nbsp; &nbsp; <script>&nbsp; &nbsp; &nbsp; &nbsp; // ask server if file exists&nbsp; &nbsp; &nbsp; &nbsp; function check() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var xhttp = new XMLHttpRequest();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xhttp.onreadystatechange = function() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (this.readyState == 4 && this.status == 200) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(this.responseText);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(this.responseText == 'True') {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // show button&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; document.getElementById("button").classList.remove("hidden");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // stop checking&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; clearTimeout(timer);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xhttp.open("GET", "/check", true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xhttp.send();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; // repeate function `check` every 1000ms (1s)&nbsp; &nbsp; &nbsp; &nbsp; var timer = setInterval(check, 1000);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; </script></body></html>''')@app.route('/check')def check():&nbsp; &nbsp; return str(os.path.isfile('file.txt'))if __name__ == '__main__':&nbsp; &nbsp; app.run()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python