[Flask] 파일 업로드 (File Upload)하기

hukim·2020년 12월 5일
0

Flask

목록 보기
4/5

HTML의 enctype 변경

기본적으로 폼태그의 enctype을 지정하지 않을 경우 디폴트로
application/x-www-form-urlencoded로 지정되기 때문에 파일을 전송하려면
반드시 enctype을 multipart/form-data로 지정해주어야 합니다.
그리고 GET 메소드는 이용할 수 없고 method도 POST를 이용해야 합니다.

HTML Example

<html>
  <body>
    <form action = "http://localhost:5000/fileupload" method = "POST"
          enctype = "multipart/form-data">
      <input type = "file" name = "file" />
      <input type = "submit"/>
    </form>
  </body>
</html>

🟠 POSTMAN에서 파일전송하기

HTML폼을 이용하지 않고 POSTMAN에서도 바로 file upload를 테스트해볼 수 있습니다.

  1. 기존에는 raw -> JSON 으로 주로 보냈다면 여기서는 form-data를 선택해줍니다.
  2. KEY 이름을 작성하고 저 부분을 클릭해서 File, Text중에서 File을 선택합니다.
  3. VALUE 에는 실제 업로드할 이미지 파일을 선택해서 등록합니다.

request.files로 파일 불러오기

기존에는 request.json을 이용해서 request의 데이터들을 그대로 받아서 이용했지만 파일을 불러올 때는 request.files['key']을 이용해서 불러옵니다.
파일 이름을 가져오고 싶을 때는 file_object.filename을 사용하면 됩니다.

file.save(path)

파일을 업로드 시킬때는 file_objects.save("경로명", "파일명")을 사용해서 업로드 시킵니다.

업로드한 파일 표시

파일이 있는 경로를 url에 입력하면 해당 이미지를 볼 수있습니다.
플라스크를 거쳐 경로를 변경하고 싶을 때는
send_from_directory("경로", "파일명")을 사용하면 해당 경로에 접근했을 때
파일을 웹 상에 띄워주게 됩니다.

파일 경로

파일 경로를 지정해주고 싶은 데 만약 각 회원의 아이디로 폴더를 구분해서 프로필 이미지를 업로드 시켜주고 싶을 때가 필요할것입니다.
이럴 경우 폴더를 미리 생성해두고 진행할 수도 없기 때문에

import os

os.makedirs(image_path, exist_ok=True)

os.makedirsexists_ok라는 옵션을 이용하면 만약 존재하지 않는 폴더의 경우는 생성시킨다는 뜻입니다.

secure_filename ?

그 전에는 werkzeug에서 import 했으나 werkzeug.utils에서 import로 변경되었음.
from werkzeug.utils import secure_filename 에서 secure_filename을 사용하는 이유는 보안상의 이유때문에 그렇습니다.

filename = "../../../../home/username/.bashrc"

위와 같은 filename을 설정했다고 생각해봅니다.

위의 filename을 secure_filename을 이용하면

>>> secure_filename("../../../../home/username/.bashrc")
'home_username_.bashrc'

다음과 같이 경로를 쉽게 알아내는 것을 방지해줍니다.

Flask File Upload Example

import os
from flask import Flask, request
from werkzeug.utils import secure_filename

app = Flask(__name__)
...

# 파일 업로드
@app.route('/fileupload', methods=['POST']
def file_upload():
	file = request.files['file']
    	
        filename = secure_filename(file.filename)
    	os.makedirs(image_path, exists_ok=True)
        file.save(os.path.join(image_path, filename)
        
        return
...

1개의 댓글

comment-user-thumbnail
2022년 4월 7일

검색해도 잘 안 나왔는데,, 너무 정리 잘 해주셔서 감사합니다ㅠㅠ

답글 달기