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-файла.