Flask
파일 업로드
수색…
통사론
- request.files [ 'name'] # 단일 필수 파일
- request.files.get ( 'name') # 게시되지 않은 경우 없음
- request.files.getlist ( 'name') # 게시 된 0 개 이상의 파일 목록
- 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>
파이썬 요청
Requests 는 HTTP 요청을하기위한 강력한 파이썬 라이브러리입니다. 브라우저 (또는 다른 도구)를 사용하여 브라우저없이 파일 을 게시 할 수 있습니다.
- 바이너리 모드로 읽을 파일을 엽니 다.
-
files
필요한 여러 데이터 구조가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
매핑 필드 이름은 파일 객체에 매핑됩니다. 동일한 필드 이름으로 여러 파일을 업로드 한 경우 []
또는 get
대신 getlist
-를 사용하십시오.
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와 WTForm을 통합하는 확장 기능인 Flask-WTF를 사용하는 경우 올바른 데이터를 전달하면 자동으로 처리됩니다.
WTForm의 버그로 인해 여러 파일을 업로드 한 경우에도 각 파일에 하나의 파일 만 표시됩니다. 자세한 내용은 이 문제 를 참조하십시오. 3.0에서 수정 될 것입니다.
PARSE 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>
어느 누구도 휠을 재발 명하고 싶지 않으므로 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 파일을 구문 분석하는 예와 관련이 있습니다.