Flask を用いたデータベースアプリケーション制作 Part3

## 環境
macOS Catalina 10.15.1

## アプリケーションの実装内容
Flask の使い方を習得すべく3つのパートに分けた。

#### [Part1 (前々稿)](https://qiita.com/keisuke-ota/items/a4dd23fbb2c9b642bb2d)
* Web ブラウザの表示
* Templates フォルダの html ファイルと連結

#### [Part2 (前稿)](https://qiita.com/keisuke-ota/items/b575f542bff6303ba4f1)
* データベース SQLite との連結
* Bootstrap を用いた画面表示

#### Part3(本稿)
* POST メソッドを用いた新規ユーザー登録

## Part3のフォルダ構成

[Part1](https://qiita.com/keisuke-ota/items/a4dd23fbb2c9b642bb2d)、[Part2](https://qiita.com/keisuke-ota/items/b575f542bff6303ba4f1) と同様に、全てのコードは run.py によって実行される。
run.py は Part1 と同じものを、 model.py は Part2 と同じものをそれぞれ使用した。

```
root
|--codes
| |--view.py
| |--templates
| | |--database.html
| | |--index3.html
|--models.py
|--run.py
|--test.db
```

## POSTメソッドを用いた新規ユーザー登録

以下に view.py を 示す。

```python:view.py
from flask import Flask,render_template, request, url_for, redirect
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker 
from models import User

app = Flask(__name__)

engine = create_engine('sqlite:///test.db')
session = sessionmaker(bind=engine)()

# /index3 へアクセスがあった場合に、index3.html を返す。
# ここで DB の新規ユーザー登録が可能。
# index3 で受けたリクエストは /register に POST メソッドで submit される。
@app.route("/index3", methods=['GET'])
def index3():
	return render_template('index3.html')

# index3.html からのリクエストを、User クラスで定義された型に従って /database に返す。
# POST メソッドによりリクエストは暗号化されているため、/register にはアクセスできない。
@app.route("/register", methods=['POST'])
def register():
	name = request.form['name']
	age = int(request.form['age'])
	new_user = User(name=name, age=age)
	session.add(new_user)
	session.commit()
	return redirect(url_for('database'))

# /database へアクセスがあった場合に、DB 画面を表示させる。新規ユーザーを次々と更新できる。
@app.route("/database", methods=['GET'])
def database():
	users = session.query(User).all()
	return render_template('database.html', users=users)

if __name__ == "__main__":
    app.run(debug=True)
```

index3.html は以下のとおり。入力データを /register に submit している。

```html:index3.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content = "width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>Document</title>
	<!-- Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
	<div class="container">
		<div class="row">
			<div class="col-md-6 col-md-offset-3">
				<hl>データの入力</hl>
			</div>
		</div>
		<div class="row">
			<div class="col-md-6 col-md-offset-3">
				<form name="signin" action="./register" method="POST">
					<input type="text" name="name" class="form-control" placeholder="Name" reqired>
					<input type="text" name="age" class="form-control" placeholder="Age" reqired>
					<button id="btn" class="btn btn-ig btn-primary btn-block" type="submit">Register</button>
				</form>
			</div>
		</div>
	</div>
</body>
</html>
```

database.html は以下のとおり。

```html:database.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content = "width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>Document</title>
	<!-- Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
	<div class="container">
		<div class="row">
			<hl>Flask チュートリアル</hl>
			<table class="table table-striped table-hover">
				<thread>
					<tr>
						<th scope="col">#</th>
						<th scope="col">Name</th>
						<th scope="col">Age</th>
					</tr>
				</thread>
				<tbody>
					{% for user in users %}
						<tr>
							<td>{{user.id}}</td>
							<td>{{user.name}}</td>
							<td>{{user.age}}</td>
						</tr>
					{% endfor %}
				</tbody>
			</table>
			<p><a href="/index3">ユーザー登録画面へ戻る</p>
		</div>
	</div>
</body>
</html>
```
同様に、http://127.0.0.1:5000/index3 にアクセスして以下が表示されていれば成功である。
<img width="825" alt="スクリーンショット 2020-04-03 18.37.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/8b66e729-e841-abb6-18b4-69b235a8cec5.png">


新規ユーザーを登録すると、http://127.0.0.1:5000/database が表示される。
![k2Hlnkd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/17789872-a24a-f6bf-b1ea-8dd1fa370b46.png)

## 参考
参考：[データ収集からWebアプリ開発まで実践で学ぶ機械学習活用ガイド](https://book.mynavi.jp/supportsite/detail/9784839969226.html) の chapter 3-5