---
# System prepended metadata

title: 07/18課程筆記
tags: [flask, 學長作業, python]

---

# 07/18課程筆記
###### tags: `學長作業` `flask` `python`
## flask快速開始
1. 在虛擬檔環境創一個`app.py`的檔案
    ```python

    from flask import Flask

    app = Flask(__name__)

    @app.route("/")
    def index():
        return "OK"


    if __name__=="__main__":    #app.py被指定執行，才會啟動Server
        app.run()
    ```
    >如果有黃色波浪在 Flask 底下等等可以先確認一下有沒有在虛擬環境下安裝flask或是否有抓到到虛擬環境的目錄，設置完重啟Vscode即可
    >![](https://i.imgur.com/utaZJBs.png =80%x)
2. 我們執行看看，我們可以在`127.0.0.1:5000`或`localhost:5000`看到return回來的字串
    ![](https://i.imgur.com/yxwaERF.png)
    
    ![](https://i.imgur.com/MidzrUT.png)
    >埠號5000是預設值
## Debug 之使用
使用Debug的好處，修改code後不用重啟Server。會自動reload
```python

from flask import Flask

app = Flask(__name__)
app.config['ENV']="development"  
app.config['DEBUG']=True        #使用Debug的好處，修改code後不用重啟Server。會自動reload

@app.route("/")
def index():
    return "OK"

@app.route("/test")
def test():
    return "this is test"


if __name__=="__main__":
    app.run()
    
```
來看看結果:
成功!
![](https://i.imgur.com/NpNqK9U.png)

## postman安裝使用
>postman是開發API京城會使用到的工具

[下載連結點及這裡](https://www.postman.com/downloads/)
* 安裝結束，開啟軟體會看到下圖介面:
    >![](https://i.imgur.com/tdlz1Oe.png =90%x)

* 我們試著用Postman來觀察我們剛剛的`localhost:5000`或`127.0.0.1:5000`會得到以下結果:

    >![](https://i.imgur.com/VZUTdV4.png =85%x)
    > 
    >![](https://i.imgur.com/OuW3deG.png =85%x)
* 得到的結果與瀏覽器得到的結果是一樣的

## POST & GET 實作
### POST
1. 先在專案目錄底下創建一個名為`templates`的資料夾，並在資料夾下創建`index.html`的檔案
    >![](https://i.imgur.com/HpF1q8i.png) 下面為index.html的code

    ```html
    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>test</title>
    </head>

    <body>
        <form method="post" , action="/test">
            <input name="abc" />
            <input type="submit">
        </form>
    </body>

    </html>

    ```
2. 看一下這個index.html長怎樣?
    >點擊專案目錄底下`index.html`
    >![](https://i.imgur.com/TgJVsYH.png)
    >
    >看一下結果，正確!
    >![](https://i.imgur.com/Wcleg9d.png)
3. 我們原本python的code要再增加一些程式碼
    >我們需要再`import render_template`，這個template是[樣板引擎](https://hackmd.io/@jddj42840/rJ94SPHnq)
    >![](https://i.imgur.com/PTCRFUt.png)
    
    >再路徑'/'底下回傳index.html的畫面，把原本要回傳的字串註解
    >![](https://i.imgur.com/yfDHXtP.png)
    
    >接收前端回傳的資料並處理(test函數沒打算處理)
    >![](https://i.imgur.com/OcMEiMT.png)

    >補充:
    >index.html內有一串叫`<form method="post" , action="/test">`
    >他的意思是將表單得到的資料用`post`的方式傳遞給`/test`這個位置

    :::spoiler
    ```python
    from flask import Flask, render_template

    app = Flask(__name__)
    app.config['ENV'] = "development"
    app.config['DEBUG'] = True  # 使用Debug的好處，修改code後不用重啟Server


    @app.route("/")
    def index():
        # return "OK"
        return render_template("index.html")


    @app.route("/test",methods=["POST"] )
    def test():
        return "this is test"


    if __name__ == "__main__":
        app.run()

    ``` 
    :::
    
    >我們點開瀏覽器先在輸入隨意輸入
    >![](https://i.imgur.com/J2CsoKo.png)
    
    >成功進入test裡面，按`F12`
    >![](https://i.imgur.com/Bxkt9lK.png)

    >點擊`NetWork` > 沒畫面按`ctrl+R` > 點擊 test
    >![](https://i.imgur.com/fcfnt3z.png)

    >在網頁檢查選單裡 在`NetWork` > `Payload`  會看到我們剛剛輸入的值
    >![](https://i.imgur.com/LGKtKXg.png)

### GET
1. 我們修改一下index.html的資料將`<form method="post" , action="/test">`<br>改為`<form method="get" , action="/test">`
    >![](https://i.imgur.com/bjvGpn3.png)

2. 在python檔案那邊將原本的`@app.route("/test", methods=["POST"])`<br>改為`@app.route("/test", methods=["GET", "POST"])`
    >![](https://i.imgur.com/fjmaZ5Y.png)
    
3. 存檔`ctrl+s`完，開啟瀏覽器，在輸入欄輸入任意~例:ABC~
    >![](https://i.imgur.com/cQRtUOv.png)
    
    >網址也顯示我們剛剛在輸入欄內輸入的值
    >![](https://i.imgur.com/eqEkhpz.png)

### 結論
1. 我們可以得知GET會將得到得值放在網址上POST不會
2. GET將我們輸入的質變成了「要求字串」(Query String)
    >要求字串基礎教程連結:[點這](https://hackmd.io/@jddj42840/ryiHo8Asq)

### postman操作練習
1. 繼續上方的練習，我們只需打開postman
2. 選擇POST，鍵入localhost網址、輸入KEY、Value、按Send
    >![](https://i.imgur.com/xmVGYYs.png)
3. 目前有輸出跟瀏覽器一樣即可，之後會交更多操作

## 導向(redirect)、url_for的使用演示
1. 我們需要在flask下載入url_for、redirect屬性
    >![](https://i.imgur.com/HLmeTBj.png)

2. 我們新增一個`/test2`路徑，這路徑的功能為利用`url_for`抓index的裝飾器參數<br>得到的值為 `/` ，將得到的值給 `redirect` 如此一來，我們再`/test2`也還是會看到`/`底下的結果 
    > ![](https://i.imgur.com/EisZNXs.png)
    :::spoiler
    ```python

    from flask import Flask, render_template, url_for, redirect

    app = Flask(__name__)
    app.config['ENV'] = "development"
    app.config['DEBUG'] = True  # 使用Debug的好處，修改code後不用重啟Server


    @app.route("/")
    def index():
        # return "OK"
        return render_template("index.html")


    @app.route("/test", methods=["GET", "POST"])
    def test():
        return "this is test"


    @app.route("/test2")
    def test2():
        return redirect(url_for("index"))


    if __name__ == "__main__":
        app.run()

    ```
    :::
## 錯誤處理與回應
我們再localhost後面增加一個未定路徑，會發生錯誤
>![](https://i.imgur.com/AYfvosY.png)
>補充:
>404...那個名叫http狀態碼，遇到不同事件狀態碼也會不同


1. 而我們要讓錯誤回復有其他呈現方式我們python檔案內新增一個錯誤處理
增加額外錯誤處理的方式
    ```python
    @app.errorhandler(404)
    def erro404(error):
        return render_template('page_not_found.html')
    ```
    ::: spoiler
    ```python
    from flask import Flask, render_template, url_for, redirect

    app = Flask(__name__)
    app.config['ENV'] = "development"
    app.config['DEBUG'] = True  # 使用Debug的好處，修改code後不用重啟Server


    @app.route("/")
    def index():
        # return "OK"
        return render_template("index.html"), 404 #指定錯誤為404


    @app.route("/test", methods=["GET", "POST"])
    def test():
        return "this is test"


    @app.route("/test2")
    def test2():
        return redirect(url_for("index"))


    @app.errorhandler(404)
    def erro404(error):
        return render_template('page_not_found.html')


    if __name__ == "__main__":
        app.run()

    ```
    :::

2. 仔細看看，ㄟ`render_template`不是樣板引擎嗎?<br>所以我們再`templates`目錄底下增加一個名叫`page_not_found.html`的檔案
    ```html
    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>找不到拉!!</title>
    </head>

    <body>
        <h1>不然你想怎樣?不能乖乖的嗎??</h1>
    </body>

    </html>
    ```
3. 我們跑跑看最一開始的404錯誤，成功 :heavy_check_mark: 
    ![](https://i.imgur.com/O0qoYiZ.png)
將路徑設為變數，不常用
## url另類使用方式
```python
@app.route('/add/<int:num1>/<int:num2>')
def add(num1, num2):
    return str(num1) + " * " + str(num2) + " = " + str(num1 * num2)
```
我們會看到
>![](https://i.imgur.com/Xyni9Za.png)

## Query String(要求字串)實作
>https://hackmd.io/@jddj42840/ryiHo8Asq
1. 我們需要用到`request`物件，皆在後面即可
    >![](https://i.imgur.com/UFelCNG.png)
2. 新增一個路徑`/test4`
    >![](https://i.imgur.com/SPiFfoe.png)

3. 我們再路徑`/test4`後面增加要求字串(Query String)`?abc=123`
    >![](https://i.imgur.com/KnQTGIJ.png)~get method~

* 我們試試看post method 吧
    1. 將更改index.html的內容，將原本的get改為post
    >![](https://i.imgur.com/ZpSXyWN.png)
    2. 更改python檔案 /test的內容
    >![](https://i.imgur.com/gmcIWTl.png)
    * 注意!python的變數名稱要與index.html檔案的input變數名字要一樣
    * 例:以本code為例:都要為abc

## 作業練習
- [x] 1. 有一個網頁路徑可以回傳樣本引擎
    >route index return template
- [x] 2. 獲得index網頁路徑form (method=POST) 的參數
    >route get index from params
- [x] 3. 有一個可以重新導向的網頁
    >route redirect
- [x] 4. 有一個網頁路徑可以利用路徑參數進行運算，類似下圖之功能
    >route params in url path
    >![](https://i.imgur.com/o5Bag0Q.png)
- [x] 5. 運用要求字串query string做一些基本的參數運算，類似下圖的功能
    >route get ? params
    >![](https://i.imgur.com/c1n6vJO.png)
- [x] 6. 錯誤處理與回應
    >error handler
:::spoiler
第一題
>![](https://i.imgur.com/XhupA6r.png)

>![](https://i.imgur.com/tI8KfUS.png)

第二題
>![](https://i.imgur.com/a2c7p7S.png)

>![](https://i.imgur.com/So1jcjD.png)

>![](https://i.imgur.com/qXTWMog.png)

第三題
>![](https://i.imgur.com/0rFwWbE.png)

>![](https://i.imgur.com/qQU2yHw.png)

>![](https://i.imgur.com/5VMsZM7.png)

第四題
>![](https://i.imgur.com/E4h8aWX.png)


>![](https://i.imgur.com/ifY58UQ.png)

第五題
>![](https://i.imgur.com/I0HUkMp.png)

>![](https://i.imgur.com/ozEjuHp.png)

>
第六題
> ![](https://i.imgur.com/j8WmRkp.png)

>![](https://i.imgur.com/U4krQMR.png)

>![](https://i.imgur.com/B2R5B39.png)

:::