LoginSignup
63
79

More than 5 years have passed since last update.

Flaskで画像アップローダー

Last updated at Posted at 2017-05-18

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

前回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

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

実行結果

スクリーンショット 2017-05-18 15.23.26.png

完成です。

63
79
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
63
79