Flask
Filuppladdningar
Sök…
Syntax
- request.files ['name'] # enstaka obligatorisk fil
- request.files.get ('name') # Inget om det inte är postat
- request.files.getlist ('namn') # lista med noll eller fler poster som har lagts in
- CombinedMultiDict ((request.files, request.form)) # kombinera form- och fildata
Ladda upp filer
HTML-formulär
- Använd en
file
och webbläsaren ger ett fält som låter användaren välja en fil som ska laddas upp. - Endast formulär med
post
metod kan skicka datafilen. - Se till att ställa in formens
enctype=multipart/form-data
attribut. Annars skickas filens namn men inte filens data. - Använd
multiple
attribut på ingången för att tillåta val av flera filer för det enda fältet.
<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 begär
Requests är ett kraftfullt Python-bibliotek för att göra HTTP-förfrågningar. Du kan använda den (eller andra verktyg) för att lägga ut filer utan webbläsare.
- Öppna filerna för att läsa i binärt läge.
- Det finns flera datastrukturer som
files
tar. Detta visar en lista med(name, data)
tuples, som tillåter flera filer som formen ovan.
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)
Detta är inte avsett att vara en uttömmande lista. För exempel med ditt favoritverktyg eller mer komplexa scenarier, se dokumenten för det verktyget.
Spara överföringar på servern
Uppladdade filer finns tillgängliga i request.files
, ett MultiDict
mappningsfältnamn för MultiDict
. Använd getlist
- istället för []
eller get
- om flera filer laddades upp med samma fältnamn.
request.files['profile'] # single file (even if multiple were sent)
request.files.getlist('charts') # list of files (even if one was sent)
Objekten i request.files
har en save
metod som sparar filen lokalt. Skapa en gemensam katalog för att spara filerna i.
filename
attribut är namnet som filen laddades upp med. Detta kan ställas in godtyckligt av klienten, så skicka det genom metoden secure_filename
för att generera ett giltigt och säkert namn att spara som. Detta säkerställer inte att namnet är unikt , så att befintliga filer kommer att skrivas om du inte gör extra arbete för att upptäcka det.
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')
Vidarebefordra data till WTForms och Flask-WTF
WTForms tillhandahåller ett FileField
att göra en filtypinmatning. Det gör inte något speciellt med den uppladdade informationen. Eftersom Flask delar upp request.form
( request.form
) och fildata ( request.files
) måste du dock se till att du skickar rätt data när du skapar formuläret. Du kan använda en CombinedMultiDict
att kombinera de två i en enda struktur som WTForms förstår.
form = ProfileForm(CombinedMultiDict((request.files, request.form)))
Om du använder Flask-WTF , ett tillägg för att integrera Flask- och WTForms, hanteras rätt data automatiskt för dig.
På grund av ett fel i WTForms kommer bara en fil att finnas i varje fält, även om flera laddades upp. Se det här problemet för mer information. Det kommer att fixas i 3.0.
PARSE CSV-FIL UPLOAD SOM LISTA FÖR DICTIONARIES I FLASK UTAN SPARA
Utvecklare behöver ofta utforma webbplatser som tillåter användare att ladda upp en CSV-fil. Vanligtvis finns det ingen anledning att spara den faktiska CSV-filen eftersom data behandlas och / eller lagras i en databas när de har laddats upp. Men många om inte de flesta, PYTHON-metoder för att analysera CSV-data kräver att data läses in som en fil. Detta kan ge lite huvudvärk om du använder FLASK för webbutveckling.
Anta att vår CSV har en rubrikrad och ser ut enligt följande:
h1,h2,h3
'yellow','orange','blue'
'green','white','black'
'orange','pink','purple'
Anta nu att HTML-formuläret för att ladda upp en fil är som följer:
<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>
Eftersom ingen vill återuppfinna hjulet väljer du att IMPORT csv i ditt FLASK- skript. Det finns ingen garanti för att folk laddar upp csv-filen med kolumnerna i rätt ordning. Om csv-filen har en rubrikrad, kan du med hjälp av metoden csv.DictReader läsa CSV-filen som en lista med ordböcker, knappade med posten i rubrikraden. Csv.DictReader behöver dock en fil och accepterar inte direkt strängar. Du kanske tror att du måste använda FLASK- metoder för att först spara den överförda filen, få det nya filnamnet och platsen, öppna den med csv.DictReader och sedan ta bort filen. Verkar som lite slöseri.
Lyckligtvis kan vi få filinnehållet som en sträng och sedan dela upp strängen med avslutade rader. Csv-metoden csv.DictReader accepterar detta som en ersättning för en fil. Följande kod visar hur detta kan åstadkommas utan att spara filen tillfälligt.
@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"
Variabeln csv_dicts är nu följande lista med ordböcker:
csv_dicts =
[
{'h1':'yellow','h2':'orange','h3':'blue'},
{'h1':'green','h2':'white','h3':'black'},
{'h1':'orange','h2':'pink','h3':'purple'}
]
Om du är ny med PYTHON kan du få åtkomst till data på följande sätt:
csv_dicts[1]['h2'] = 'white'
csv_dicts[0]['h3'] = 'blue'
Andra lösningar involverar import av io- modulen och använder metoden io.Stream . Jag känner att det här är en mer enkel strategi. Jag tror att koden är lite lättare att följa än att använda io- metoden. Detta tillvägagångssätt är specifikt för exemplet med att analysera en uppladdad CSV-fil.