読者です 読者をやめる 読者になる 読者になる

ポーカー、プログラミング、もぐ

ポーカーとプログラミングともぐもぐについてのブログ。

Flask on Heroku(Python3.4.2) その3 入力フォームを作る

Flask on Heroku(Python3.4.2) その1 環境構築 - ポーカー、プログラミング、もぐ

Flask on Heroku(Python3.4.2) その2 Hello World - ポーカー、プログラミング、もぐ

今回は、indexページに入力フォームをつけます。

Flaskでフォームを利用する時、ライブラリを利用するとバリデーションやHTMLの生成など、
フォーム周りの処理が楽になります。
今回はWTFormsを、Flask-WTFを使って利用します。

1,設定ファイルの作成
WTFormsを利用するために必要な設定を保存する、設定ファイルを作成します。

projectnameディレクトリ下に、config.pyファイルを作成します。

WTF_CSRF_ENABLED = True
SECRET_KEY = 'hogehoge'

WTF_CSRF_ENABLEDは、CSRF対策を行うかどうかの設定です。
WTF_CSRF_ENABLEDをTrueとした場合、SECRET_KEYを設定する必要があります。
SECRET_KEYは、推測が難しい文字列を入力します。

また、この設定を読み込ませるため、__init__.pyファイルを変更します。

from flask import Flask
app = Flask(__name__)
app.config.from_object('config')

from flask_app import views

app.config.from_object('config') の一行を追加します。

2,Formクラスの作成
WTFormsを利用する場合、まずフォームに対応するクラスを作成しなければいけません。
flask_appディレクトリ下に、forms.pyファイルを作成します。

from flask.ext.wtf import Form
from wtforms import StringField, TextAreaField
from wtforms.validators import DataRequired, Length

class TodoForm(Form):
    title = StringField('title', validators=[DataRequired()])
    detail = TextAreaField('detail', validators=[Length(min=0, max=5000)])

3,viewへの追加
views.pyファイルを編集します。

from flask import render_template, flash, redirect, url_for, request

from flask_app import app
from .forms import TodoForm

@app.route('/')
def hello_world():
    return "Hello World!"

@app.route('/register', methods=['GET', 'POST'])
def register():
    form = TodoForm()
    if request.method == 'POST' and form.validate():
        title = form.title.data
        detail = form.detail.data
        flash('title:{title}, detail:{detail}'.format(title=title, detail=detail))
        return redirect(url_for('register'))

    return render_template('register.html',
                           form=form)

変更点は以下の通りです。
・from flask import render_template, flash, redirect, url_for, request
を追加します。

・from .forms import TodoForm
を追加します。

・routeデコレータを使って、/registerのURLとregister関数を紐付けます。
register関数の中では、以下の処理を行っています。
form = TodoForm() : 先ほど作成したTodoFormクラスのインスタンスを生成しています。
if request.method == 'POST' and form.validate(): :POSTメソッドが利用され、かつフォームが正しく入力された時。以下のブロックでは、
フォームが入力・送信された時の処理を記述しています。
title = form.title.data、detail = form.detail.data  : フォームの入力値を変数にセットしています。
flash('title:{title}, detail:{detail}'.format(title=title, detail=detail)) : メッセージを受け渡しするためのflashを使っています。
return redirect(url_for('register')) : /registerへリダイレクトさせています。

return render_template('register.html',form=form):render_template関数を使って、HTMLを生成し返しています。

4,テンプレートの生成
templatesディレクトリ下に、register.htmlファイルを作成します。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>register</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
  {% if messages %}
    <ul class=flashes>
    {% for message in messages %}
      <li>{{ message }}</li>
    {% endfor %}
    </ul>
  {% endif %}
{% endwith %}

<h2>REGISTER</h2>
  <form action="" method="post" name="register">
      {{ form.hidden_tag() }}
      <p>
          title:<br>
          {{ form.title() }}<br>
      </p>
      {% for error in form.title.errors %}
            <span style="color: red;">TITLEを入力してください。</span>
          {% endfor %}<br>

      <p>
          detail:<br>
          {{ form.detail() }}<br>
      </p>
      <p><input type="submit" value="投稿"></p>
  </form>


</body>
</html>

ここまで編集が終わったら、
http://127.0.0.1:5000/register
へアクセスします。
f:id:asiagohan:20150718184649j:plain
上記のようなページが表示されます。

フォームに入力して「投稿」ボタンを押すと、
f:id:asiagohan:20150718184701j:plain
入力された値がページ上に表示されます。