Flask
Datei-Uploads
Suche…
Syntax
- request.files ['name'] # einzelne erforderliche Datei
- request.files.get ('name') # Keine, falls nicht gepostet
- request.files.getlist ('name') # Liste von null oder mehr Dateien
- CombinedMultiDict ((request.files, request.form)) # fügt Formular- und Dateidaten zusammen
Dateien hochladen
HTML-Formular
- Verwenden Sie eine
file
Eingabe, und der Browser stellt ein Feld bereit, in dem der Benutzer eine Datei zum Hochladen auswählen kann. - Nur Formulare mit der
post
Methode können Dateidaten senden. -
enctype=multipart/form-data
Sie sicher, dass dasenctype=multipart/form-data
Attribut des Formularsenctype=multipart/form-data
. Andernfalls wird der Dateiname gesendet, nicht jedoch die Daten der Datei. - Verwenden Sie das Attribut
multiple
für die Eingabe, um die Auswahl mehrerer Dateien für das einzelne Feld zu ermöglichen.
<form method=post enctype=multipart/form-data>
<!-- single file for the "profile" field -->
<input type=file name=profile>
<!-- multiple files for the "charts" field -->
<input type=file multiple name=charts>
<input type=submit>
</form>
Python-Anfragen
Requests ist eine leistungsfähige Python-Bibliothek zum Erstellen von HTTP-Anfragen. Sie können es (oder andere Tools) verwenden, um Dateien ohne Browser zu veröffentlichen.
- Öffnen Sie die Dateien, um sie im Binärmodus zu lesen.
-
files
haben mehrere Datenstrukturen. Dies demonstriert eine Liste von(name, data)
Tupeln, die mehrere Dateien wie das obige Formular zulässt.
import requests
with open('profile.txt', 'rb') as f1, open('chart1.csv', 'rb') as f2, open('chart2.csv', 'rb') as f3:
files = [
('profile', f1),
('charts', f2),
('charts', f3)
]
requests.post('http://localhost:5000/upload', files=files)
Dies ist keine erschöpfende Liste. Beispiele mit Ihrem bevorzugten Werkzeug oder komplexeren Szenarien finden Sie in den Dokumenten für dieses Werkzeug.
Speichern Sie Uploads auf dem Server
Hochgeladene Dateien sind in request.files
verfügbar, einem MultiDict
Zuordnungsfeldnamen zu MultiDict
. Verwenden Sie getlist
- anstelle von []
oder get
-, wenn mehrere Dateien mit demselben Feldnamen hochgeladen wurden.
request.files['profile'] # single file (even if multiple were sent)
request.files.getlist('charts') # list of files (even if one was sent)
Die Objekte in request.files
verfügen über eine save
, mit der die Datei lokal gespeichert wird. Erstellen Sie ein allgemeines Verzeichnis, in dem die Dateien gespeichert werden sollen.
Das filename
Attribut ist der Name, mit dem die Datei hochgeladen wurde. Dieser kann vom Client willkürlich festgelegt werden. Durchlaufen Sie die Methode secure_filename
, um einen gültigen und sicheren Namen zum Speichern zu generieren. Dies stellt nicht sicher, dass der Name eindeutig ist , sodass vorhandene Dateien überschrieben werden, sofern Sie nicht noch dazu extra arbeiten.
import os
from flask import render_template, request, redirect, url_for
from werkzeug import secure_filename
# Create a directory in a known location to save files to.
uploads_dir = os.path.join(app.instance_path, 'uploads')
os.makedirs(uploads_dir, exists_ok=True)
@app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
# save the single "profile" file
profile = request.files['profile']
profile.save(os.path.join(uploads_dir, secure_filename(profile.filename)))
# save each "charts" file
for file in request.files.getlist('charts'):
file.save(os.path.join(uploads_dir, secure_filename(file.name)))
return redirect(url_for('upload'))
return render_template('upload.html')
Daten an WTForms und Flask-WTF übergeben
WTForms stellt ein FileField
zum Rendern einer Dateityp-Eingabe FileField
. Es macht nichts Besonderes mit den hochgeladenen Daten. Da Flask jedoch die Formulardaten ( request.form
) und die request.files
( request.files
) request.files
, müssen Sie beim Erstellen des Formulars sicherstellen, dass die richtigen Daten übergeben werden. Sie können CombinedMultiDict
, um die beiden in einer einzigen Struktur zu kombinieren, die WTForms versteht.
form = ProfileForm(CombinedMultiDict((request.files, request.form)))
Wenn Sie Flask-WTF verwenden , eine Erweiterung, um Flask und WTForms zu integrieren, werden die korrekten Daten automatisch für Sie verarbeitet.
Aufgrund eines Fehlers in WTForms ist für jedes Feld nur eine Datei vorhanden, selbst wenn mehrere hochgeladen wurden. Weitere Informationen finden Sie in dieser Ausgabe . Es wird in 3.0 behoben.
PARSE CSV-DATEI HOCHLADEN ALS LISTE DER WÖRTERBÜCHER IN FLASK OHNE EINSPARUNG
Entwickler müssen häufig Websites erstellen, auf denen Benutzer eine CSV-Datei hochladen können. Normalerweise gibt es keinen Grund , die aktuelle CSV - Datei zu speichern , da die Daten verarbeitet und / oder in einer Datenbank einmal hochgeladen gespeichert. Bei vielen, wenn nicht den meisten, PYTHON-Methoden zum Analysieren von CSV-Daten müssen die Daten jedoch als Datei eingelesen werden. Dies kann zu Kopfschmerzen führen, wenn Sie FLASK für die Webentwicklung verwenden.
Angenommen, unser CSV hat eine Kopfzeile und sieht wie folgt aus:
h1,h2,h3
'yellow','orange','blue'
'green','white','black'
'orange','pink','purple'
Angenommen, das HTML-Formular zum Hochladen einer Datei lautet wie folgt:
<form action="upload.html" method="post" enctype="multipart/form-data">
<input type="file" name="fileupload" id="fileToUpload">
<input type="submit" value="Upload File" name="submit">
</form>
Da niemand das Rad neu erfinden möchte, entscheiden Sie sich dafür, csv in Ihr FLASK- Skript zu importieren . Es gibt keine Garantie dafür, dass Benutzer die CSV-Datei mit den Spalten in der richtigen Reihenfolge hochladen. Wenn die csv-Datei eine Kopfzeile hat, können Sie die CSV-Datei mit Hilfe der Methode csv.DictReader als Liste von Wörterbüchern lesen, die durch die Einträge in der Kopfzeile eingegeben werden. Csv.DictReader benötigt jedoch eine Datei und akzeptiert keine Zeichenfolgen direkt. Möglicherweise müssen Sie FLASK- Methoden verwenden, um die hochgeladene Datei zuerst zu speichern, den neuen Dateinamen und den neuen Speicherort abzurufen , sie mit csv.DictReader zu öffnen und die Datei anschließend zu löschen. Scheint wie eine Verschwendung.
Glücklicherweise können wir den Inhalt der Datei als Zeichenfolge abrufen und die Zeichenfolge dann durch terminierte Zeilen aufteilen. Die csv-Methode csv.DictReader akzeptiert dies als Ersatz für eine Datei. Der folgende Code veranschaulicht, wie dies erreicht werden kann, ohne die Datei vorübergehend zu speichern.
@application.route('upload.html',methods = ['POST'])
def upload_route_summary():
if request.method == 'POST':
# Create variable for uploaded file
f = request.files['fileupload']
#store the file contents as a string
fstring = f.read()
#create list of dictionaries keyed by header row
csv_dicts = [{k: v for k, v in row.items()} for row in csv.DictReader(fstring.splitlines(), skipinitialspace=True)]
#do something list of dictionaries
return "success"
Die Variable csv_dicts ist jetzt die folgende Liste von Wörterbüchern:
csv_dicts =
[
{'h1':'yellow','h2':'orange','h3':'blue'},
{'h1':'green','h2':'white','h3':'black'},
{'h1':'orange','h2':'pink','h3':'purple'}
]
Falls Sie mit PYTHON noch nicht vertraut sind, können Sie auf folgende Daten zugreifen:
csv_dicts[1]['h2'] = 'white'
csv_dicts[0]['h3'] = 'blue'
Andere Lösungen beinhalten das IO - Modul importieren und die io.Stream Methode verwenden. Ich denke, dass dies ein direkter Ansatz ist. Ich glaube, dass der Code etwas einfacher zu befolgen ist als die Verwendung der IO- Methode. Dieser Ansatz ist spezifisch für das Beispiel der Analyse einer hochgeladenen CSV-Datei.