---
# System prepended metadata

title: 第5回 高木研勉強会

---

# 第5回 高木研勉強会

## 準備

* Flaskをインストール
```
pip install flask
```

* Werkzeug
```
pip install Werkzeug
```

* 次のディレクトリー構造を作成しよう
```
.
├── static
│   ├── css
│   │   └── style.css
│   └── js
│       └── style.js
├── templates
│   └── index_page.html
└── web_app.py
```

## とりあえず、Web_appを完成させよう

* web_app.py
``` python=
from flask import Flask, render_template, request

app = Flask(__name__)

@app.route("/", methods=["GET"])
def index_page():
    text = "test_text"
    return render_template("index_page.html", text = text)

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

* index_page.html
```html=
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="../static/css/style.css">
    </head>
    <body>
        <h1>{{text}}</h1>
    </body>
</html>
```

* 実行
```
python web_app.py
```
`localhost:5000`にアクセスする。

## 少しcssで装飾

* style.css
```css=
body{
    background-color: aquamarine;
}
h1{
    color: darkblue;
}
```

## postページを作成

* `templates`に`result_page.html`を作成。
* web_app.pyに以下のコードを追記
```python=
@app.route("/result_page", methods=["GET","POST"])
def result_page():
    #データが届いたら
    if request.method == "POST":
        # 値のデータを取得
        text = request.form["post_text"]
    return render_template("result_page.html", text = text)
```

* index_page.htmlを以下のように変更
```html=
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="../static/css/style.css">
    </head>
    <body>
        <h1>{{text}}</h1>
        <form action="/result_page" method=post enctype="multipart/form-data">
            <input type="text" name="post_text">
            <input type = submit value = Upload>
        </form>
    </body>
</html>
```

* result_page.html
```html=
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="../static/css/style.css">
    </head>
    <body>
        <h1>{{text}}</h1>
    </body>
</html>
```

## 画像をアップロードできるようになろう

* `web_app`に`uploads`ディレクトリーを作成

* web_app.pyを以下に変更
```pyyhon=
from flask import Flask, render_template, request
import os
from werkzeug.utils import secure_filename

# 画像をアップロードするフォルダー
upload_folder = './uploads'
# 画像の拡張子の制限
# set()で重複した要素を取り除く
allowed_extenstions = set(["png","jpg","jpeg"])

# お決まり
app = Flask(__name__)
app.secret_key = "hogehoge"

# 設定の保存
# upload_folderの設定を保存
UPLOAD_FOLDER = './uploads/'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# configの読み込み
app.config.from_object(__name__)

@app.route("/", methods=["GET"])
def index_page():
    text = "test_text"
    return render_template("index_page.html", text = text)

@app.route("/result_page", methods=["GET","POST"])
def result_page():
    text= ""
    #データが届いたら
    if request.method == "POST":
        # 値のデータを取得
        text = request.form["post_text"]
        # ファイルを読み込む
        img_file = request.files['img_file']
        print(img_file)
        # 拡張子を取得する
        filename = secure_filename(img_file.filename)
        print(filename)
        # 画像のアップロード先URLを生成する
        img_url = os.path.join(app.config["UPLOAD_FOLDER"], "test."+filename)
        # 画像をアップロード先に保存する
        img_file.save(img_url)
    return render_template("result_page.html", text = text)

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

* index_page.htmlに次の`input`タグを追記
```html=
<input type="text" name="post_text"><br>
<input type="file" id="img_file" name="img_file"><br>
<input type = "submit" value = "Upload">
```

## modalウィンドウを作成しよう


* index_page.htmlの`body`に次のものを追記
```html=
<br>
<button id="modalOpen" class="modal-button">modalTest</button>
<div id="easyModal" class="modal">
    <div class="modal-content">
        <div class="modal-header">
            <h1>Test</h1>
            <span class="modalClose">×</span>
        </div>
    </div>
    <div class="modal-body">
        <h1>body</h1>
    </div>
</div>
<script src="../static/js/style.js"></script>
```

* style.js
```javascript=
window.addEventListener('DOMContentLoaded', function() {
    modal_process("modalOpen","easyModal","modalClose");
});

function modal_process(modalOpenId, easyModal, modalCloseId){
    const buttonOpen = document.getElementById(modalOpenId);
    const modal = document.getElementById(easyModal);
    const buttonClose = document.getElementsByClassName(modalCloseId)[0];

    buttonOpen.addEventListener('click', modalOpen);
    function modalOpen() {
        modal.style.display = 'block';
    }

    buttonClose.addEventListener('click', modalClose);
    function modalClose() {
        modal.style.display = 'none';
    }

    addEventListener('click', outsideClose);
    function outsideClose(e) {
        if (e.target == modal) {
            modal.style.display = 'none';
        }
    }
}
```

* style.cssを以下のように変更
```css=
body{
    background-color: aquamarine;
}
h1{
    color: darkblue;
}

.modal-button{
    background: rgb(230, 173, 221);
    color: #fff;
    border: 0;
    width: 500px;
    height: 100px;
    font-size: 45px;
    border-radius: 5px;
    font-weight: 900;
    left: 400px;
    top: 260px;
    font-family: serif;
}

.modal-button:hover{
    background: rgb(230, 173, 221);
    cursor: pointer;
}

.modal{
    display: none;
    position: fixed;
    z-index: 1;
    left: 0;
    top: 0;
    height: 100%;
    width: 100%;
    overflow: auto;
    background-color: rgba(0, 0, 0, 0.5);
}

.modal-content{
    background-color: #f4f4f4;
    margin: 20% auto;
    width: 50%;
    box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2),0 7px 20px 0 rgba(0, 0, 0, 0.17);
    animation-name: modalopen;
    animation-duration: 1s;
}

.modal-header h1{
    margin: 1rem 0;
}

.modal-header{
    background: rgb(230, 173, 221);
    padding: 3px 15px;
    display: flex;
    justify-content: space-between;
}

.modal-body {
    padding: 10px 20px;
    color: black;
}

.modalClose{
    font-size: 2rem;
}

.modalClose:hover{
    cursor: pointer;
}

@keyframes modalopen {
    from {opacity: 0}
    to {opacity: 1}
}
```