iT邦幫忙

3

[不做怎麼知道系列之Android開發者的30天後端養成故事 Day6] - 運用框架的槓桿 #前後端怎麼結合 #框架的威力 #Django Template Engine

Sam 2020-02-08 22:47:474066 瀏覽
  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20200208/20124548cDKGkemrXC.png

大家好,我們又見面了,昨天我們說要聊聊 API 這檔事,但 RS 在 Python Django Web Framework - Full Course for Beginners 教學影片,看到了一個很酷的東西,忍不住就研究了進去,RS 要對不起那些期待 API 的捧油們了,今天我們先來看看 DjangoTemplate Engine 有多厲害 !

其實我在開始學習後端之前,完全不能理解到底 框架 是什麼,就算別人再怎麼解釋我還是不能理解,有使用框架 和 沒使用框架 所寫出來的網站,到底差在哪裡?

今天我們就來看看,Django 這個框架裡面的 Template Engine 幫我們做了哪些事情吧~

先講結論,我們後面再來慢慢消化理解

Django 的 Template Engine 幫我們把 資料 帶到 畫面 上,而且還附帶了許多有用而且好玩的功能。

前面幾篇我一直沒有提到的,就是 Django 將 MVC Pattern (Model-View-Controller Pattern) 換成 MVT Pattern (Model-View-Template Pattern),簡單來說,Model 負責處理資料庫的格式、View 負責連接 資料 與 畫面、Template 負責把資料放到畫面上,這樣做的好處就是強迫使用 django 的人們,都能夠寫出乾淨、邏輯清晰的程式碼,多多少少拉 XD,有興趣可以參考 Django 介紹 | MDN,在這邊先借跟 MDN 一張圖讓大家有點感覺。

https://mdn.mozillademos.org/files/13931/basic-django.png

Django 的 MVT 架構圖,圖片來自 Django 介紹 | MDN

所以 Template Engine 做了什麼 ?

你可以在 views.py 裡面從 database 讀取資料,並且透過 template engine 把 views.py 裡面的資料以 context 的形式傳遞給 html 檔,不懂嗎 ? 來看個例子吧。

資料怎麼從 views.py 傳到 index.html 呢 ?

這邊假設已經從資料庫裡面抓出資料、存放在變數裡,並且塞到 context 中。

blog/views.py

from django.shortcuts import render
    
def hello(request):
  # 我們塞了一個 string、一個 float 給 context
  # 並且透過 template engine,將這個 context
  # 傳遞給 index.html (這就是框架幫我們做的)
  context = {
      "first_var": "Hello Man",
      "second_var": 8787.87
  }
  return render(request, 'blog/index.html', context)

templates/blog/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RS shop</title>
    <h1 align="center">RS 的 Django 測試</h1>
</head>
<body>
    <div align="center">
        <form method="post" action="./api/username">
            你的名字:<input type="text" name="username" placeholder="name"> <button type="submit">送出</button>
        </form>
    </div>
</body>
    
<br>
    
<div>
<!-- 我們只要透過兩個大括號包起來
     就可以取用到放在 context 裡的資料了 -->
var: {{ first_var }} and {{ second_var }}
</div>
    
<br>
    
<footer>
    <div align="center">Made by RS, 2020-02-07</div>
</footer>
    
</html>

出來的結果會長這樣

https://ithelp.ithome.com.tw/upload/images/20200208/20124548uHDpdUt59p.png

搭拉~ 我們成功從 html 以變數的方式,拿到存放在 views.py 的資料,而且還放到畫面上了,這一切都是 template engine 幫我們做到的 <3 ,謝謝你 9527

https://ithelp.ithome.com.tw/upload/images/20200208/201245482toAV72TXP.jpg

圖片來自 唐伯虎點秋香,經典台詞來自 周星馳

在 HTML 也可以寫 For Loop ? (Template Tag)

哪泥,竟然有這回事 !

來人,上範例!

blog/views.py

from django.shortcuts import render
    
def hello(request):
  context = {
      "first_var": "Hello Man",
      "second_var": 87.8787,
      # 新增第三個變數,是個 list
      "third_list": ["歡迎", "你好", "我是 RS"]
  }
  return render(request, 'blog/index.html', context)

templates/blog/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RS shop</title>
    <h1 align="center">RS 的 Django 測試</h1>
</head>
<body>
    <div align="center">
        <form method="post" action="./api/username">
            你的名字:<input type="text" name="username" placeholder="name"> <button type="submit">送出</button>
        </form>
    </div>
</body>
    
<br>
<div>
    <!-- 這是我們剛剛寫的 -->
    var: {{ first_var }} and {{ second_var }}.
    
    <!-- 用子彈清單的方式,
    列出 context 裡的 list -->
    <ul>
        <!-- 其實就是 python 的 for 語法 -->
        {% for sub_item in third_list %}
            <li>
                {{ sub_item }}
            </li>
        <!-- 別忘了要封起來 -->
        {% endfor %}
    </ul>
</div>
    
<br>
    
<footer>
    <div align="center">Made by RS, 2020-02-07</div>
</footer>
    
</html>

結果長這樣

https://ithelp.ithome.com.tw/upload/images/20200208/20124548kdQcuSSdYB.png

哇呼,成功 again!更多的 template tags 可以參考官方文件

那該不會也可以在 HTML 寫 if else ? 偷偷告訴你,還可以做加法呢 (Template Tag Filter)

blog/views.py

from django.shortcuts import render
    
def hello(request):
    context = {
        "first_var": "Hello Man",
		"second_var": 87.8787,
        # 新增一筆用來比對的字串在 list 裡
		"third_list": ["歡迎", "你好", "我是 RS", "來比對我阿"]
    }
    return render(request, 'blog/index.html', context)

templates/blog/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RS shop</title>
    <h1 align="center">RS 的 Django 測試</h1>
</head>
<body>
    <div align="center">
        <form method="post" action="./api/username">
            你的名字:<input type="text" name="username" placeholder="name"> <button type="submit">送出</button>
        </form>
    </div>
</body>
    
<br>
<div>
    var: {{ first_var }} and {{ second_var }}.
    
    <ul>
        {% for sub_item in third_list %}
            <!-- 經典 python if else 語法 -->
            {% if sub_item == "來比對我阿" %}
                <li>
                    <!-- 這根直槓槓,
                    就是 django template filter -->
                    {{ second_var|add:100 }}
                </li>
            {% elif sub_item == "你好" %}
                <li>
                    真正高興地見到你
                </li>
            {% else %}
                <li>
                    {{ sub_item }}
                </li>
            {% endif %}
        {% endfor %}
    </ul>
</div>
    
<br>
    
<footer>
    <div align="center">Made by RS, 2020-02-07</div>
</footer>
    
</html>

結果是

https://ithelp.ithome.com.tw/upload/images/20200208/20124548yEyX5aHT1h.png

第二句原本在 list 裡的是 "你好",成功替換成 "真正高興地見到你",以及第四句原本應該是 "來比對我阿",比對到並且對 87.8787 + 100,並且默默被轉成 int,所以得出 187。更多關於 Django template tag filter 請參考官方文件

看到這裡,是不是受不了 index.html 了 ?

就等你這句,沒錯,他好長好煩,有沒有方法可以解決呢 ?

把會重複用到的部分拆到 base.html,再繼承就好了 !

templates/blog/base.html

我們把 head 和 footer 放在 base.html 裡,其他的 html 頁面就可以專注在,每個頁面該做的事情上。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RS shop</title>
    <h1 align="center">RS 的 Django 測試</h1>
</head>
<body>
    <!-- content 是個變數名稱,
    可以隨意取沒關係。 -->
    {% block content %}
    {% endblock %}
</body>
    
<footer>
    <div align="center">Made by RS, 2020-02-07</div>
</footer>
    
</html>

templates/blog/index.html

<!-- django template tag 
讓我們能夠繼承其他 html -->
{% extends "blog/base.html" %}
    
<!-- 輸入相同的 block 名稱
就可以在被繼承的地方插入 -->
{% block content %}
<div align="center">
    <form method="post" action="./api/username">
        你的名字:<input type="text" name="username" placeholder="name"> <button type="submit">送出</button>
     </form>
</div>
    
<br>
<div>
    var: {{ first_var }} and {{ second_var }}.
    
    <ul>
        {% for sub_item in third_list %}
            {% if sub_item == "來比對我阿" %}
                <li>
                    {{ second_var|add:100 }}
                </li>
            {% elif sub_item == "你好" %}
                <li>
                    真正高興地見到你
                </li>
            {% else %}
                <li>
                    {{ sub_item }}
                </li>
            {% endif %}
        {% endfor %}
    </ul>
</div>
    
<br>
    
<!-- 依舊別忘了 closing -->
{% endblock %}

結果與拆開前,一模模一樣樣

https://ithelp.ithome.com.tw/upload/images/20200208/20124548Ta56wdZKHt.png

這個繼承的功能,也是來自 django template tag,有興趣可以參考官方文件

單日心得總結

先跟期待原本要寫的 API 主題的捧油們說對不起 QQ,當我看影片看到 template engine 所帶來的效果時,就是這個 aha-moment,發現原來 這就是框架的意義!真的是解惑了我長久以來的疑問,很興奮所以改了主題來跟大家分享這個美麗的時刻 XD。

今天是我的發文挑戰中的第一個假日,除了原本假日的生活外,需要再自己找時間來完成今天的發文任務,其實對我來說這是一件很有意義的事,每天讓自己都有產出,可以讓我的自信保持在一定的水平,相比之下,原本的我在假日很沒有目標,即使是耍廢、玩耍,也不會很開心,過完兩天假日就有一種「蛤,怎麼又要上班了。」的感覺,這種感覺是一種 沒有滿足 的感覺,然後週而復始地循環,我花了很長的時間才讓自己脫離這種狀態,有空再來細聊這個話題~

明天來跟大家聊聊,到底要怎麼從後端拿到資料,再呈現到網頁畫面上呢?

我是 RS,這是我的 不做怎麼知道系列 文章,我們 明天見。



圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言