본문 바로가기

웹개발

게시판(flask)-파일 업로드, 다운로드

파일 업로드, 다운로드 기능을 만들기 위해 먼저 필요한 라이브러리들을 import 한다.

from werkzeug.utils import secure_filename
import os
from flask import send_from_directory

그리고 mysql에서 posts 테이블에 filename이라는 속성을 만든다.

mysql> ALTER TABLE posts ADD COLUMN filename VARCHAR(255) NULL;

 

<업로드>

UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'pptx', 'hwp', 'hwpx', 'docx'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

root디렉토리에 uploads 폴더를 만들고 거기로 파일을 저장하게 한다.

파일의 확장자를 미리 지정해서 이상한 파일을 업로드하지 못하게 한다.

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS



file = request.files['file']

if file and allowed_file(file.filename):
    filename = secure_filename(file.filename)
    file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
    
query = "INSERT INTO posts (title, content, username, filename) values (%s, %s, %s, %s)"
value = (title, content, username, filename)

write 링크에서 파일을 posts 테이블에 추가하는 부분을 작성하였다.

allowed_file 함수로 허용된 파일인지 검사한다.

 

<다운로드>

@app.route('/download/<filename>')
def download(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename, as_attachment=True)

다운로드를 하는 링크를 만들어서 flask의 내장함수 send_from_directory로 파일을 보내준다.

as_attachment=True를 설정하지 않으면 파일이 다운받아지는게 아니라 웹브라우저에서 열려버린다.

{% if post.filename %}
<a href="{{ url_for('download', filename=post.filename) }}">파일 다운로드</a>
<br>
{% endif %}

read.html에서 filename이 있으면 파일을 다운로드하는 링크는 보여주게 만들었다.

파일 다운로드 버튼을 누르면 잘 다운되는 것을 확인하였다.