80
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated 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

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

実行結果

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

完成です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
80
Help us understand the problem. What are the problem?