LoginSignup
45
36

More than 3 years have passed since last update.

POST送信されたパラメータをFlaskで受けるときにrequest has no attribute 'form'(ついでにFlaskのスタートアップガイド)

Last updated at Posted at 2019-09-13

目的

研修用の教材をFlaskで作っていて、リクエストパラメータを受け取るときにハマったので。

序盤は普通にFlaskチュートリアルっぽい感じです。
ハマったところまで飛ばしたい方はハマった話結論へどうぞ。

やったこと

まずはHello World

pipやcondaを使ってflaskをインストールしておきます。

pip install flask

その後、適当なディレクトリにプログラムを作っていきます。

app.py
# coding: utf-8
from flask import Flask, render_template

# Webサーバインスタンスの生成
app = Flask(__name__) 

# http://localhost:5000/にリクエストが来たときの処理
@app.route("/")
def index():
    return "Hello Flask!"

if __name__ == "__main__":
    # webサーバーの立ち上げ
    app.run()

その後、コンソール上でapp.pyが保存されているディレクトリまで移動し、

python app.py

これでサーバが立ち上がりました。

image.png

問題なさそうです。

「ログイン画面→ようこそ、◯◯さん」まで作る

次に、リクエストパラメータを試してみたかったので、フォームへの入力+画面遷移のところまでやってみようと思いました。

ログイン画面の作成

リクエストパラメータを受け取ってみようということになって、とりあえずログイン画面を作りました。ログイン画面なので、よく見る感じでPOST送信にしておきます。
また、ユーザ名はusername、パスワードはpasswordという名前で送信されることにしておきます。
また、formのaction属性はとりあえずlogin_managerとしておきます。後ほど使います。

login.html
<html>
    <head>

    </head>

    <body>
        <form action="/login_manager" method="POST">
            <input type="text" name="username" placeholder="Your name">
            <input type="password" name="password" placeholder="Your password">
            <input type="submit" value="login">
        </form>
    </body>
</html>

app.pyへの登録

先程のapp.pyで分かる通り、app.pyはURLと実行される処理の紐付けを行っているような立ち位置なので、このlogin.htmlに関してもapp.pyへ追加しておきます。

app.py
# coding: utf-8
from flask import Flask, render_template

app = Flask(__name__) 

@app.route("/")
def index():
    return "Hello Flask!"

@app.route("/login") #追加
def login():
    return render_template("login.html")

if __name__ == "__main__":
    # webサーバー立ち上げ
    app.run()

サーバを再度立ち上げて、今度はhttp://localhost/loginで試してみます。
image.png
問題なさそう。

app.pyに処理を追加

http://localhost:5000/login_managerにリクエストが来たときの処理をapp.pyに追加します。login_managerは、以前にlogin.htmlを作成したときのformのaction属性で指定しています。

app.py
# coding: utf-8
from flask import Flask, render_template

app = Flask(__name__) 

@app.route("/")
def index():
    return "Hello Flask!"

@app.route("/login") 
def login():
    return render_template("login.html")

@app.route("/login_manager", methods=["POST"])  #追加
def login_manager():
    return "ようこそ、" + request.form["username"] + "さん"

if __name__ == "__main__":
    # webサーバー立ち上げ
    app.run()

ハマった話

さて、ここがハマった話です。
上のコードのlogin_manager部分で、requet.form["username"]としているのですが、いざリクエストを送ってみると...
image.png

な、なにぃ~~

慌ててサーバログを除くと...

return "ようこそ、" + request.form["username"] + "さん"
NameError: name 'request' is not defined

あ、はいはいわかったわかった。
import requestだな!と思ってimport文をapp.pyに追加。

意気揚々とサーバを再起動するも、またもや500番台エラー。
ただ良くログを見ると今度は若干違っていて...

return "ようこそ、" + request.form["username"] + "さん"
AttributeError: module 'request' has no attribute 'form'

結論

import request

ではなく

from flask import request

でした。

同一モジュール名ですが、パッケージが違っていたようです。
常識かもしれないんだけど、初心者からするとなんともややこしい。

まとめ

FlaskでPOST送信されたパラメータを受け取りたいときはこう。

from flask import request

実際にPOST送信されたパラメータを受け取るときはこう。

request.form["パラメータ名"]

ちなみに、GET送信されたパラメータの場合はこうらしい。

request.args.get("パラメータ名")
45
36
2

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
45
36