kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

HFP2: 最初のWebアプリ

Flaskのインストールから 

$ pip install Flask
...
Successfully installed Flask-1.0.2 Jinja2-2.10.1 MarkupSafe-1.1.1 Werkzeug-0.15.2 itsdangerous-1.1.0

hello_flask.pyを作成して少しずつ付け加えていく

/にアクセスして“Hello world from Flask!”を表示

/search4にアクセスしてsearch4lettersの結果を表示
(固定文字列なのでまだフォームは出てきてない)
from vsearch import search4lettersが成功している

テンプレートの利用

ベーステンプレート
{% block body %}から{% endblock %}までが置き換わる
{{ 式 }} で式の結果を埋め込む

<!DOCTYPE html>
<html>
    <head>
        <title>{{ the_title }}</title>
        <link rel="stylesheet" href="static/hf.css" />
    </head>
    <body>
        {% block body %}

        {% endblock %}
    </body>
</html>

置き換えるにはextendsディレクティブを使う

{% extends 'base.html' %}

{% block body %}

<h2>{{ the_title }}</h2>

<form method="POST" action="/search4">
    ...
</form>

{% endblock %}

CSSは/staticに、テンプレートは/templatesに置く

コードでは
@app.route()でURLを指定する
render_templateを使ってHTMLを返す
フォームの要素にアクセスするにはrequest.form辞書を使う

デバッグモードにしたいときにはrunメソッドにdebug=Trueを追加
そうするとコードを修正するたびにWebアプリが自動的にリロードされる

リダイレクトするにはredirect('/entry')を返す
はいいとして’302’ていったい何

@app.route("/")
def hello() -> '302':
    return redirect('/entry')

'302'は型として認められているのか
mypyがInvalid type comment or annotationと言ってるから違うんだろな
Python単体としてはエラーじゃないとしても

mypyに通してもらうにはどう書くべきか
redirect('/entry')は実際何を返している?302?いやー

$ py
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from flask import Flask, render_template, request, redirect
>>> rd = redirect('/entry')
>>> rd
<Response 219 bytes [302 FOUND]>
>>> type(rd)
<class 'werkzeug.wrappers.response.Response'>
>>> dir(rd)
[..., 'data', ..., 'headers', ..., 'status_code', ...]
>>> rd.status_code
302
>>> rd.headers
Headers([('Content-Type', 'text/html; charset=utf-8'), ('Content-Length', '219'), ('Location', '/entry')])
>>> rd.location
'/entry'
>>> rd.data
b'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n<title>Redirecting...</title>\n<h1>Redirecting...</h1>\n<p>You should be redirected automatically to target URL: <a href="/entry">/entry</a>.  If not click the link.'
>>>

すくなくともただの302ではない
定義を見てみる(抜粋)

def redirect(location, code=302, Response=None):
    """Returns a response object (a WSGI application) that, if called,
    redirects the client to the target location. ...
    """
    ...
    response = Response(
        '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
        ...,
        mimetype="text/html",
    )
    response.headers["Location"] = location
    return response

Response型、かな

でもdef hello() -> 'Response':では
Name 'Response' is not definedと言われる

これで文句言われなくなったけどすこし釈然としない

from werkzeug.wrappers import Response

@app.route("/")
def hello() -> Response:
    return redirect("/entry")

mypyの細かいことがそもそもわかってないしこのへんにしておく