Zoeken…


Syntaxis

  • request.files ['name'] # vereist enkel bestand
  • request.files.get ('name') # Geen indien niet gepost
  • request.files.getlist ('name') # lijst met nul of meer geposte bestanden
  • CombinedMultiDict ((request.files, request.form)) # combineer formulier- en bestandsgegevens

Bestanden uploaden

HTML-formulier

  • Gebruik een file invoer en de browser zal een veld verschaffen waarmee de gebruiker een bestand kan selecteren om te uploaden.
  • Alleen formulieren met de post methode kunnen bestandsgegevens verzenden.
  • Zorg ervoor dat u het kenmerk enctype=multipart/form-data het formulier enctype=multipart/form-data . Anders wordt de bestandsnaam verzonden, maar niet de gegevens van het bestand.
  • Gebruik het multiple attribuut op de invoer om meerdere bestanden voor het enkele veld te selecteren.
<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-aanvragen

Verzoeken is een krachtige Python-bibliotheek voor het maken van HTTP-aanvragen. Je kunt het (of andere hulpmiddelen) gebruiken om bestanden te plaatsen zonder een browser.

  • Open de bestanden om te lezen in binaire modus.
  • Er zijn meerdere datastructuren die files neemt. Dit toont een lijst met (name, data) tupels, waarmee meerdere bestanden zoals het bovenstaande formulier kunnen worden gebruikt.
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)

Dit is niet bedoeld als een uitputtende lijst. Voor voorbeelden met uw favoriete tool of meer complexe scenario's raadpleegt u de documenten voor die tool.

Bewaar uploads op de server

Geüploade bestanden zijn beschikbaar in request.files , een MultiDict die veldnamen MultiDict aan bestandsobjecten. Gebruik getlist - in plaats van [] of get - als er meerdere bestanden met dezelfde veldnaam zijn geüpload.

request.files['profile']  # single file (even if multiple were sent)
request.files.getlist('charts')  # list of files (even if one was sent)

De objecten in request.files hebben een save die het bestand lokaal opslaat. Maak een gemeenschappelijke map om de bestanden in op te slaan.

Het kenmerk filename is de naam waarmee het bestand is geüpload. Dit kan willekeurig door de client worden ingesteld, dus geef het door de methode secure_filename om een geldige en veilige naam te genereren om op te slaan als. Dit zorgt er niet voor dat de naam uniek is , dus bestaande bestanden worden overschreven, tenzij u extra werk doet om dat te detecteren.

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')

Gegevens doorgeven aan WTForms en Flask-WTF

WTForms biedt een FileField om een bestandstype-invoer te maken. Het doet niets speciaals met de geüploade gegevens. Aangezien Flask de formuliergegevens ( request.form ) en de bestandsgegevens ( request.files ) splitst, moet u er echter voor zorgen dat u de juiste gegevens doorgeeft wanneer u het formulier maakt. U kunt een CombinedMultiDict gebruiken om de twee te combineren in een enkele structuur die WTForms begrijpt.

form = ProfileForm(CombinedMultiDict((request.files, request.form)))

Als u Flask-WTF gebruikt , een extensie om Flask en WTForms te integreren, wordt het doorgeven van de juiste gegevens automatisch voor u verwerkt.

Vanwege een fout in WTForms is er slechts één bestand aanwezig voor elk veld, zelfs als er meerdere zijn geüpload. Zie dit probleem voor meer informatie. Het zal worden opgelost in 3.0.

PARSE CSV-BESTAND UPLOAD ALS LIJST MET WOORDEN IN FLAS ZONDER BESPARING

Ontwikkelaars moeten vaak websites ontwerpen waarmee gebruikers een CSV-bestand kunnen uploaden. Meestal is er geen reden om het eigenlijke CSV-bestand op te slaan, omdat de gegevens na het uploaden worden verwerkt en / of opgeslagen in een database. Veel, zo niet de meeste, PYTHON-methoden voor het parseren van CSV-gegevens vereisen dat de gegevens als een bestand worden ingelezen. Dit kan een beetje hoofdpijn opleveren als u FLASK gebruikt voor webontwikkeling.

Stel dat onze CSV een koprij heeft en er als volgt uitziet:

h1,h2,h3
'yellow','orange','blue'
'green','white','black'
'orange','pink','purple'

Stel nu dat het HTML-formulier om een bestand te uploaden als volgt is:

<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>

Omdat niemand het wiel opnieuw wil uitvinden, besluit u csv in uw FLASK- script te IMPORTEREN . Er is geen garantie dat mensen het csv-bestand met de kolommen in de juiste volgorde uploaden. Als het csv-bestand een koprij heeft, kunt u met behulp van de methode csv.DictReader het CSV-bestand lezen als een lijst met woordenboeken, ingetoetst door de vermeldingen in de koprij. Csv.DictReader heeft echter een bestand nodig en accepteert niet direct tekenreeksen. U denkt misschien dat u FLASK- methoden moet gebruiken om eerst het geüploade bestand op te slaan, de nieuwe bestandsnaam en locatie op te halen, het te openen met csv.DictReader en vervolgens het bestand te verwijderen. Lijkt een beetje zonde.

Gelukkig kunnen we de bestandsinhoud als een string ophalen en de string vervolgens opsplitsen door afgebroken lijnen. De csv-methode csv.DictReader accepteert dit als vervanging van een bestand. De volgende code laat zien hoe dit kan worden bereikt zonder het bestand tijdelijk op te slaan.

@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"

De variabele csv_dicts is nu de volgende lijst met woordenboeken:

   csv_dicts = 
    [
        {'h1':'yellow','h2':'orange','h3':'blue'},
        {'h1':'green','h2':'white','h3':'black'},
        {'h1':'orange','h2':'pink','h3':'purple'}
    ]

Als PYTHON nieuw voor u is, kunt u toegang krijgen tot gegevens zoals de volgende:

csv_dicts[1]['h2'] = 'white'
csv_dicts[0]['h3'] = 'blue'

Andere oplossingen zijn het importeren van de io- module en het gebruik van de io.Stream- methode. Ik heb het gevoel dat dit een eenvoudiger aanpak is. Ik geloof dat de code iets gemakkelijker te volgen is dan met de io- methode. Deze benadering is specifiek voor het voorbeeld van het parseren van een geüpload CSV-bestand.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow