Szukaj…


Składnia

  • request.files ['name'] # pojedynczy wymagany plik
  • request.files.get ('name') # Brak, jeśli nie zostało opublikowane
  • request.files.getlist ('name') # lista zero lub więcej opublikowanych plików
  • CombinedMultiDict ((request.files, request.form)) # łączy dane formularza i pliku

Przesyłanie plików

Formularz HTML

  • Użyj file wejściowych typu file a przeglądarka wyświetli pole, które pozwala użytkownikowi wybrać plik do przesłania.
  • Tylko formularze z metodą post mogą wysyłać dane pliku.
  • Pamiętaj, aby ustawić enctype=multipart/form-data . W przeciwnym razie nazwa pliku zostanie wysłana, ale nie dane pliku.
  • Użyj atrybutu multiple na wejściu, aby umożliwić wybranie wielu plików dla pojedynczego pola.
<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>

Zapytania w języku Python

Żądania to potężna biblioteka Pythona do wykonywania żądań HTTP. Możesz używać go (lub innych narzędzi) do publikowania plików bez przeglądarki.

  • Otwórz pliki do odczytu w trybie binarnym.
  • files przyjmują wiele struktur danych. To pokazuje listę krotek (name, data) , która pozwala na wiele plików, takich jak powyższy formularz.
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)

To nie jest wyczerpująca lista. Przykłady użycia ulubionego narzędzia lub bardziej złożonych scenariuszy znajdują się w dokumentacji tego narzędzia.

Zapisz przesłane pliki na serwerze

Przesłane pliki są dostępne w request.files , MultiDict pól mapowania MultiDict na obiekty plików. Użyj getlist - zamiast [] lub get - jeśli przesłano wiele plików o tej samej nazwie pola.

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

Obiekty w request.files mają save metodę, która zapisuje plik lokalnie. Utwórz wspólny katalog do zapisywania plików.

Atrybut filename to nazwa, z którą plik został przesłany. Może to być ustawione dowolnie przez klienta, więc przekaż je za pomocą metody secure_filename , aby wygenerować prawidłową i bezpieczną nazwę do zapisania jako. Nie gwarantuje to, że nazwa jest unikalna , więc istniejące pliki zostaną zastąpione, chyba że wykonasz dodatkową pracę, aby to wykryć.

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

Przekazywanie danych do WTForms i Flask-WTF

WTForms zapewnia FileField do renderowania danych wejściowych typu pliku. Nie robi nic specjalnego z przesłanymi danymi. Ponieważ jednak Flask dzieli dane formularza ( request.form ) i dane pliku ( request.files ), musisz upewnić się, że przekazałeś poprawne dane podczas tworzenia formularza. Możesz użyć CombinedMultiDict aby połączyć je w jedną strukturę zrozumiałą dla WTForms.

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

Jeśli używasz Flask-WTF , rozszerzenia do integracji Flask i WTForms, przekazywanie poprawnych danych zostanie automatycznie przetworzone.

Z powodu błędu w WTForms, dla każdego pola będzie obecny tylko jeden plik, nawet jeśli przesłano wiele plików. Zobacz ten problem, aby uzyskać więcej informacji. Zostanie to naprawione w wersji 3.0.

PRZECZYTAJ PLIK CSV PRZEKAZYWANY JAKO LISTĘ SŁOWNIKÓW FLOKI BEZ OSZCZĘDNOŚCI

Programiści często muszą projektować witryny internetowe, które pozwalają użytkownikom na przesyłanie pliku CSV. Zwykle nie ma powodu, aby zapisać rzeczywisty plik CSV, ponieważ dane zostaną przetworzone i / lub zapisane w bazie danych po przesłaniu. Jednak wiele, jeśli nie większość, metod PYTHON analizowania danych CSV wymaga odczytania danych w postaci pliku. Może to powodować trochę bólu głowy, jeśli używasz FLASK do programowania stron internetowych.

Załóżmy, że nasz plik CSV ma wiersz nagłówka i wygląda następująco:

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

Załóżmy teraz, że formularz HTML do przesłania pliku wygląda następująco:

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

Ponieważ nikt nie chce wymyślać koła ponownie, IMPORTUJ csv do skryptu FLASK . Nie ma gwarancji, że ludzie prześlą plik csv z kolumnami we właściwej kolejności. Jeśli plik csv ma wiersz nagłówka, to przy pomocy metody csv.DictReader możesz odczytać plik CSV jako listę słowników, wpisaną w wpisy w wierszu nagłówka. Jednak csv.DictReader potrzebuje pliku i nie akceptuje bezpośrednio ciągów. Możesz pomyśleć, że musisz użyć metod FLASK , aby najpierw zapisać przesłany plik, uzyskać nową nazwę i lokalizację pliku, otworzyć go za pomocą csv.DictReader , a następnie usunąć plik. To trochę marnotrawstwo.

Na szczęście możemy pobrać zawartość pliku jako ciąg, a następnie podzielić ciąg za pomocą zakończonych linii. Metoda csv csv.DictReader zaakceptuje to jako substytut pliku. Poniższy kod pokazuje, jak można to osiągnąć bez tymczasowego zapisywania pliku.

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

Zmienna csv_dicts jest teraz następującą listą słowników:

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

Jeśli jesteś nowy w PYTHON, możesz uzyskać dostęp do danych w następujący sposób:

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

Inne rozwiązania obejmują importowanie modułu io i użycie metody io.Stream . Uważam, że jest to prostsze podejście. Uważam, że kod jest nieco łatwiejszy do naśladowania niż przy użyciu metody io . To podejście jest specyficzne dla przykładu analizowania przesłanego pliku CSV.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow