수색…


통사론

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

어느 누구도 휠을 재발 명하고 싶지 않으므로 csvFLASK 스크립트로 가져 오기 로 결정했습니다. 사람들이 정확한 순서로 열과 함께 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 파일을 구문 분석하는 예와 관련이 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow