簡體   English   中英

使用Flask上傳和下載文件

[英]Uploading and Downloading Files with Flask

我正在嘗試使用PythonAnywhere和Flask編寫一個非常簡單的webapp,它允許用戶上傳文本文件,生成csv文件,然后讓用戶下載csv文件。 它不一定是花哨的,它只需要工作。 我已經編寫了從驅動器上的txt文件生成csv的程序。

現在,我的函數打開驅動器上的文件:

with open(INPUTFILE, "r") as fname:

並編寫csv:

with open(OUTPUTFILE, 'w') as fname:

INPUTFILE和OUTPUTFILE是文件名字符串。

對於我來說,將文件作為對象處理會更好嗎,不知怎的?

我不知道該怎么做。 我該如何構建這個程序? 我需要多少個HTML模板? 我寧願在沒有將它們保存到任何地方的情況下處理文件,但如果我必須將它們保存到PythonAnywhere目錄,我可以。 我怎樣才能做到這一點?

PythonAnywhere dev在這里。 這是一個關於Flask和web開發的一個很好的問題,而不是我們系統的具體問題,所以我會嘗試給出一個沒有任何特定的通用答案:-)

有一些事情我需要知道,以便對你的問題給出明確的答案,所以我首先列出我正在做的假設 - 如果我對他們中的任何一個錯了,請給我一個評論。我會適當地更新答案。

  • 我假設您上傳的文件不是很大並且可以放入合理的內存量 - 比方說,小於一兆字節。
  • 我假設您已經編寫的用於從文本文件生成CSV的程序是在Python中,並且它具有(或者更可能,可能很容易更改為具有)包含字符串的字符串的函數文本文件的內容,並返回需要寫入CSV的內容。

如果兩者都是這種情況,那么構建Flask應用程序的最佳方法是處理Flask中的所有內容。 一個代碼示例值得千言萬語,所以這里有一個簡單的例子,我允許用戶上傳一個文本文件,通過一個名為transform的函數運行它(這是轉換程序中的函數插入的函數 - 我的只需在整個文件中替換= with ,然后將結果發送回瀏覽器。 這里有關於PythonAnywhere的這個應用程序的實時版本

from flask import Flask, make_response, request

app = Flask(__name__)

def transform(text_file_contents):
    return text_file_contents.replace("=", ",")


@app.route('/')
def form():
    return """
        <html>
            <body>
                <h1>Transform a file demo</h1>

                <form action="/transform" method="post" enctype="multipart/form-data">
                    <input type="file" name="data_file" />
                    <input type="submit" />
                </form>
            </body>
        </html>
    """

@app.route('/transform', methods=["POST"])
def transform_view():
    request_file = request.files['data_file']
    if not request_file:
        return "No file"

    file_contents = request_file.stream.read().decode("utf-8")

    result = transform(file_contents)

    response = make_response(result)
    response.headers["Content-Disposition"] = "attachment; filename=result.csv"
    return response

關於你的其他問題:

  • 模板:我沒有在這個例子中使用模板,因為我希望所有這些都適合單個代碼。 如果我正確地執行它,那么我會將form視圖生成的內容放入模板中,但這就是全部。
  • 你可以通過寫入文件來做到 - 是的,你可以,並且可以使用我使用的stream屬性的file對象上的save( filename )方法保存上傳的文件。 但是如果你的文件非常小(根據我的假設),那么在內存中處理它們可能比上面的代碼更有意義。

我希望一切都有所幫助,如果您有任何疑問,請發表評論。

最好添加

response.headers["Cache-Control"] = "must-revalidate"
response.headers["Pragma"] = "must-revalidate"
response.headers["Content-type"] = "application/csv"

如果您不添加內容類型,FF 48.0將其報告為html並為HTML打開一次“保存”對話框,然后為CSV打開。 如果您不添加Cache-Control,您的結果可能會被緩存,如果您提供活動內容,則這不是您想要的。 如果你使用must-revalidate沒有年齡,它將有效地作為無緩存 - 請參閱此處此處的解釋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM