Flask
Загрузка файлов
Поиск…
Синтаксис
- request.files ['name'] # одиночный требуемый файл
- request.files.get ('name') # Нет, если не отправлено
- request.files.getlist ('name') # список ноль или более файлов
- CombinedMultiDict ((request.files, request.form)) # объединить форму и данные файла
Загрузка файлов
Форма HTML
- Используйте
fileввод типа и браузер обеспечит поле , которое позволяет пользователю выбрать файл для загрузки. - Только формы с методом
postмогут отправлять данные файла. - Обязательно установите
enctype=multipart/form-data. В противном случае имя файла будет отправлено, но не данные файла. - Используйте
multipleатрибут на входе, чтобы разрешить выбор нескольких файлов для одного поля.
<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
Запросы - это мощная библиотека Python для создания HTTP-запросов. Вы можете использовать его (или другие инструменты) для публикации файлов без браузера.
- Откройте файлы для чтения в двоичном режиме.
- Есть несколько структур данных, которые принимают
files. Это демонстрирует список кортежей(name, data), который позволяет использовать несколько файлов, таких как форма выше.
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)
Это не должно быть исчерпывающим списком. Примеры использования вашего любимого инструмента или более сложных сценариев см. В документах для этого инструмента.
Сохранить закачки на сервере
Загруженные файлы доступны в файлах request.files , MultiDict полей MultiDict для файловых объектов. Используйте getlist - вместо [] или get - если несколько файлов были загружены с тем же именем поля.
request.files['profile'] # single file (even if multiple were sent)
request.files.getlist('charts') # list of files (even if one was sent)
Объекты в файле request.files имеют метод save который сохраняет файл локально. Создайте общий каталог для сохранения файлов.
Атрибут filename - это имя, в которое был загружен файл. Это может быть задано произвольно клиентом, поэтому передайте его с помощью метода secure_filename чтобы создать допустимое и безопасное имя для сохранения. Это не гарантирует уникальности имени , поэтому существующие файлы будут перезаписаны, если вы не выполните дополнительную работу по его обнаружению.
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')
Передача данных в WTForms и Flask-WTF
WTForms предоставляет FileField для визуализации ввода типа файла. Он не делает ничего особенного с загруженными данными. Однако, поскольку Flask разбивает данные формы ( request.form ) и данные файла ( request.files ), вам необходимо обязательно передать правильные данные при создании формы. Вы можете использовать CombinedMultiDict чтобы объединить их в одну структуру, которую понимает WTForms.
form = ProfileForm(CombinedMultiDict((request.files, request.form)))
Если вы используете Flask-WTF , расширение для интеграции Flask и WTForms, передача правильных данных будет обрабатываться автоматически.
Из-за ошибки в WTForms для каждого поля будет присутствовать только один файл, даже если несколько файлов были загружены. См. Этот вопрос для получения более подробной информации. Он будет исправлен в версии 3.0.
ФАЙЛ PARW CSV ЗАГРУЗИТ КАК СПИСОК СЛОВАРЕЙ НА ФЛАКЕ БЕЗ ЭКОНОМИКИ
Разработчикам часто приходится создавать веб-сайты, которые позволяют пользователям загружать CSV-файл. Обычно нет необходимости сохранять фактический CSV-файл, поскольку данные будут обработаны и / или сохранены в базе данных после загрузки. Однако многие, если не большинство, методы PYTHON для разбора CSV-данных требуют, чтобы данные считывались как файл. Это может привести к головной боли, если вы используете FLASK для веб-разработки.
Предположим, что наш CSV имеет строку заголовка и выглядит следующим образом:
h1,h2,h3
'yellow','orange','blue'
'green','white','black'
'orange','pink','purple'
Теперь предположим, что форма html для загрузки файла выглядит следующим образом:
<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>
Поскольку никто не хочет изобретать колесо, вы решили использовать IMPORT csv в своем сценарии FLASK . Нет никакой гарантии, что люди загружат файл csv с столбцами в правильном порядке. Если у csv-файла есть строка заголовка, то с помощью метода csv.DictReader вы можете прочитать CSV-файл в виде списка словарей, с помощью записей в строке заголовка. Однако csv.DictReader нуждается в файле и не принимает непосредственно строки. Вы можете подумать, что вам нужно использовать методы FLASK, чтобы сначала сохранить загруженный файл, получить новое имя и местоположение файла, открыть его с помощью csv.DictReader , а затем удалить файл. Кажется, что это пустая трата.
К счастью, мы можем получить содержимое файла в виде строки, а затем разбить строку на завершенные строки. Метод csv csv.DictReader примет это как замену файлу. Следующий код демонстрирует, как это можно сделать без временного сохранения файла.
@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"
Переменная csv_dicts теперь представляет собой следующий список словарей:
csv_dicts =
[
{'h1':'yellow','h2':'orange','h3':'blue'},
{'h1':'green','h2':'white','h3':'black'},
{'h1':'orange','h2':'pink','h3':'purple'}
]
Если вы новичок в PYTHON, вы можете получить доступ к следующим данным:
csv_dicts[1]['h2'] = 'white'
csv_dicts[0]['h3'] = 'blue'
Другие решения включают импорт модуля io и использование метода io.Stream . Я считаю, что это более простой подход. Я считаю, что код немного проще, чем использовать метод io . Этот подход специфичен для примера анализа загруженного CSV-файла.