Edited at

Flaskで画像アップローダー


簡易的な画像アップローダーを作成する

前回Twitter投稿クライアントを作成したので、Flaskのインストールとかは省略します。

 http://qiita.com/Gen6/items/ff1d163acf0fa7687454


テンプレートを作る


index.html

{% extends "base.html" %}

{% block content %}
<form method="post" action="/send" enctype="multipart/form-data">
<input type="file" id="img_file" name="img_file" class="col-sm-4">
<input type="submit" value="送信" class="btn">
</form>
{% if img_url %}
<p><img src="{{ img_url }}"></p>
{% endif %}
{% endblock %}

enctype="multipart/form-data" が重要です。


base.html

<!DOCTYPE html>

<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/css/style.css">
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<title>File</title>
</head>
<body>
<div class="container">
<div class="row">
{% block content %}
{% endblock %}
</div>
</div>
</body>
</html>


アプリケーションを作成する

後はファイルアップロードを作っていきます。SQlite3は今後使うかもしれないのでインポートしてるだけです。


upload.py

import os

import sqlite3
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, session
from werkzeug import secure_filename
app = Flask(__name__)

UPLOAD_FOLDER = './uploads'
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'gif'])
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['SECRET_KEY'] = os.urandom(24)

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

@app.route('/')
def index():
if 'username' in session:
return render_template('index.html')
return '''
<p>ログインしてください</p>
'''

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
if username == 'admin':
session['username'] = request.form['username']
return redirect(url_for('index'))
else:
return '''<p>ユーザー名が違います</p>'''
return '''
<form action="" method="post">
<p><input type="text" name="username">
<p><input type="submit" value="Login">
</form>
'''

@app.route('/logout')
def logout():
session.pop('username', None)
return redirect(url_for('index'))

@app.route('/send', methods=['GET', 'POST'])
def send():
if request.method == 'POST':
img_file = request.files['img_file']
if img_file and allowed_file(img_file.filename):
filename = secure_filename(img_file.filename)
img_file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
img_url = '/uploads/' + filename
return render_template('index.html', img_url=img_url)
else:
return ''' <p>許可されていない拡張子です</p> '''
else:
return redirect(url_for('index'))

@app.route('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

if __name__ == '__main__':
app.debug = True
app.run()


前回同様ログインしないとアップロードできない仕様にしてみました。アップロードを許可するファイルは

ALLOWED_EXTENSIONS = set(['png', 'jpg', 'gif'])

こんな感じで、.txtとかそこらを許可することも出来ますから結果として画像以外のアップローダーにもカスタマイズは容易です。シークレットキーがないと駄目ぽなので、

app.config['SECRET_KEY'] = os.urandom(24)

生成してます。

今回はたちまち、画像のアップロード結果だけ見たいので

img_url = '/uploads/' + filename

ダサい書き方をしてますのであしからず。


実行結果

完成です。