【Flask使用】全知識md文檔,4大部分60頁第3篇:Flask模板使用和案例

本文的主要內容:flask視圖&路由、虛擬環境安裝、路由各種定義、狀態保持、cookie、session、模板基本使用、過濾器&自定義過濾器、模板代碼復用:宏、繼承/包含、模板中特有變量和函數、Flask-WTF 表單、CSRF、數據庫操作、ORM、Flask-SQLAlchemy、增刪改查操作、案例、藍圖、單元測試

全套Flask筆記直接地址: 請移步這里


共 4 章,42 子模塊


模板

  • 基本使用
  • 過濾器&自定義過濾器
  • 控制代碼塊
  • 宏、繼承、包含
  • Flask 的模板中特有變量和方法
  • web表單
  • CSRF

學習目標

  • 能夠寫出 jinja2 中變量代碼塊和控制代碼塊的格式
  • 能夠寫出在模板中字典,列表的取值方式
  • 能夠寫出數組反轉的自定義過濾器(使用1種方式即可)
  • 能夠說出Flask中模板代碼復用的三種方式
  • 能夠使用代碼實現模板繼承的功能
  • 能夠說出可以在模板中直接使用的 Flask 變量和函數
  • 能夠使用 Flask-WTF 擴展實現注冊表單
  • 能夠說出 CSRF 攻擊的原理

模板的使用

  • 在項目下創建 templates 文件夾,用于存放所有的模板文件,并在目錄下創建一個模板html文件 temp_demo1.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
我的模板html內容
</body>
</html>
  • 設置 templates 文件夾屬性以便能夠在代碼中有智能提示

  • 設置 html 中的模板語言,以便在 html 有智能提示

  • 創建視圖函數,將該模板內容進行渲染返回
@app.route('/')
def index():return render_template('temp_demo1.html')

訪問:http://127.0.0.1:5000/ 運行測試

  • 代碼中傳入字符串,列表,字典到模板中
@app.route('/')
def index():# 往模板中傳入的數據my_str = 'Hello 黑馬程序員'my_int = 10my_array = [3, 4, 2, 1, 7, 9]my_dict = {'name': 'xiaoming','age': 18}return render_template('temp_demo1.html',my_str=my_str,my_int=my_int,my_array=my_array,my_dict=my_dict)
  • 模板中代碼
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
我的模板html內容
<br/>{{ my_str }}
<br/>{{ my_int }}
<br/>{{ my_array }}
<br/>{{ my_dict }}</body>
</html>
  • 運行效果

我的模板html內容
Hello 黑馬程序員
10
[3, 4, 2, 1, 7, 9]
{‘name’: ‘xiaoming’, ‘age’: 18}Code injected by live-server

  • 相關運算,取值
<br/> my_int + 10 的和為:{{ my_int + 10 }}
<br/> my_int + my_array第0個值的和為:{{ my_int + my_array[0] }}
<br/> my_array 第0個值為:{{ my_array[0] }}
<br/> my_array 第1個值為:{{ my_array.1 }}
<br/> my_dict 中 name 的值為:{{ my_dict['name'] }}
<br/> my_dict 中 age 的值為:{{ my_dict.age }}
  • 結果
my_int + 10 的和為:20 
my_int + my_array第0個值的和為:13 
my_array 第0個值為:3 
my_array 第1個值為:4 
my_dict 中 name 的值為:xiaoming 
my_dict 中 age 的值為:18

過濾器

過濾器的本質就是函數。有時候我們不僅僅只是需要輸出變量的值,我們還需要修改變量的顯示,甚至格式化、運算等等,而在模板中是不能直接調用 Python 中的某些方法,那么這就用到了過濾器。

使用方式:

  • 過濾器的使用方式為:變量名 | 過濾器。
{{variable | filter_name(*args)}}
  • 如果沒有任何參數傳給過濾器,則可以把括號省略掉
{{variable | filter_name}}
  • 如:``,這個過濾器的作用:把變量variable 的值的首字母轉換為大寫,其他字母轉換為小寫

鏈式調用

在 jinja2 中,過濾器是可以支持鏈式調用的,示例如下:

{{ "hello world" | reverse | upper }}

常見內建過濾器

字符串操作

  • safe:禁用轉義
<p>{{ '<em>hello</em>' | safe }}</p>
  • capitalize:把變量值的首字母轉成大寫,其余字母轉小寫
<p>{{ 'hello' | capitalize }}</p>
  • lower:把值轉成小寫
<p>{{ 'HELLO' | lower }}</p>
  • upper:把值轉成大寫
<p>{{ 'hello' | upper }}</p>
  • title:把值中的每個單詞的首字母都轉成大寫
<p>{{ 'hello' | title }}</p>
  • reverse:字符串反轉
<p>{{ 'olleh' | reverse }}</p>
  • format:格式化輸出
<p>{{ '%s is %d' | format('name',17) }}</p>
  • striptags:渲染之前把值中所有的HTML標簽都刪掉
<p>{{ '<em>hello</em>' | striptags }}</p>

列表操作

  • first:取第一個元素
<p>{{ [1,2,3,4,5,6] | first }}</p>
  • last:取最后一個元素
<p>{{ [1,2,3,4,5,6] | last }}</p>
  • length:列表長度
<p>{{ [1,2,3,4,5,6] | length }}</p>
  • sum:列表求和
<p>{{ [1,2,3,4,5,6] | sum }}</p>
  • sort:列表排序
<p>{{ [6,2,3,1,5,4] | sort }}</p>

語句塊過濾

{% filter upper %}#一大堆文字#
{% endfilter %}

自定義過濾器

過濾器的本質是函數。當模板內置的過濾器不能滿足需求,可以自定義過濾器。自定義過濾器有兩種實現方式:

  • 一種是通過Flask應用對象的 add_template_filter 方法
  • 通過裝飾器來實現自定義過濾器

重要:自定義的過濾器名稱如果和內置的過濾器重名,會覆蓋內置的過濾器。

需求:添加列表反轉的過濾器

方式一

通過調用應用程序實例的 add_template_filter 方法實現自定義過濾器。該方法第一個參數是函數名,第二個參數是自定義的過濾器名稱:

def do_listreverse(li):# 通過原列表創建一個新列表temp_li = list(li)# 將新列表進行返轉temp_li.reverse()return temp_liapp.add_template_filter(do_listreverse,'lireverse')
方式二

用裝飾器來實現自定義過濾器。裝飾器傳入的參數是自定義的過濾器名稱。

@app.template_filter('lireverse')
def do_listreverse(li):# 通過原列表創建一個新列表temp_li = list(li)# 將新列表進行返轉temp_li.reverse()return temp_li
  • 在 html 中使用該自定義過濾器
<br/> my_array 原內容:{{ my_array }}
<br/> my_array 反轉:{{ my_array | lireverse }}
  • 運行結果
my_array 原內容:[3, 4, 2, 1, 7, 9] 
my_array 反轉:[9, 7, 1, 2, 4, 3]

控制代碼塊

控制代碼塊主要包含兩個:

- if/else if /else / endif
- for / endfor

if語句

Jinja2 語法中的if語句跟 Python 中的 if 語句相似,后面的布爾值或返回布爾值的表達式將決定代碼中的哪個流程會被執行:

{%if user.is_logged_in() %}<a href='/logout'>Logout</a>
{% else %}<a href='/login'>Login</a>
{% endif %}

過濾器可以被用在 if 語句中:

{% if comments | length > 0 %}There are {{ comments | length }} comments
{% else %}There are no comments
{% endif %}

循環

  • 我們可以在 Jinja2 中使用循環來迭代任何列表或者生成器函數
{% for post in posts %}<div><h1>{{ post.title }}</h1><p>{{ post.text | safe }}</p></div>
{% endfor %}
  • 循環和if語句可以組合使用,以模擬 Python 循環中的 continue 功能,下面這個循環將只會渲染post.text不為None的那些post:
{% for post in posts if post.text %}<div><h1>{{ post.title }}</h1><p>{{ post.text | safe }}</p></div>
{% endfor %}
  • 在一個 for 循環塊中你可以訪問這些特殊的變量:
變量描述
loop.index當前循環迭代的次數(從 1 開始)
loop.index0當前循環迭代的次數(從 0 開始)
loop.revindex到循環結束需要迭代的次數(從 1 開始)
loop.revindex0到循環結束需要迭代的次數(從 0 開始)
loop.first如果是第一次迭代,為 True 。
loop.last如果是最后一次迭代,為 True 。
loop.length序列中的項目數。
loop.cycle在一串序列間期取值的輔助函數。見下面示例程序。
  • 在循環內部,你可以使用一個叫做loop的特殊變量來獲得關于for循環的一些信息

    • 比如:要是我們想知道當前被迭代的元素序號,并模擬Python中的enumerate函數做的事情,則可以使用loop變量的index屬性,例如:
{% for post in posts%}
{{loop.index}}, {{post.title}}
{% endfor %}
  • 會輸出這樣的結果
1, Post title
2, Second Post
  • cycle函數會在每次循環的時候,返回其參數中的下一個元素,可以拿上面的例子來說明:
{% for post in posts%}
{{loop.cycle('odd','even')}} {{post.title}}
{% endfor %}
  • 會輸出這樣的結果:
odd Post Title
even Second Post

示例程序

  • 實現的效果

  • 準備數據
  # 只顯示4行數據,背景顏色依次為:黃,綠,紅,紫my_list = [{"id": 1,"value": "我愛工作"},{"id": 2,"value": "工作使人快樂"},{"id": 3,"value": "沉迷于工作無法自拔"},{"id": 4,"value": "日漸消瘦"},{"id": 5,"value": "以夢為馬,越騎越傻"}
]
  • 模板代碼
{% for item in my_list if item.id != 5 %}{% if loop.index == 1 %}<li style="background-color: orange">{{ item.value }}</li>{% elif loop.index == 2 %}<li style="background-color: green">{{ item.value }}</li>{% elif loop.index == 3 %}<li style="background-color: red">{{ item.value }}</li>{% else %}<li style="background-color: purple">{{ item.value }}</li>{% endif %}
{% endfor %}

模板代碼復用

在模板中,可能會遇到以下情況:

  • 多個模板具有完全相同的頂部和底部內容
  • 多個模板中具有相同的模板代碼內容,但是內容中部分值不一樣
  • 多個模板中具有完全相同的 html 代碼塊內容

像遇到這種情況,可以使用 JinJa2 模板中的 宏、繼承、包含來進行實現

對宏(macro)的理解:

  • 把它看作 Jinja2 中的一個函數,它會返回一個模板或者 HTML 字符串
  • 為了避免反復地編寫同樣的模板代碼,出現代碼冗余,可以把他們寫成函數以進行重用
  • 需要在多處重復使用的模板代碼片段可以寫入單獨的文件,再包含在所有模板中,以避免重復

使用

  • 定義宏
{% macro input(name,value='',type='text') %}<input type="{{type}}" name="{{name}}"value="{{value}}" class="form-control">
{% endmacro %}
  • 調用宏
{{ input('name' value='zs')}}
  • 這會輸出
<input type="text" name="name"value="zs" class="form-control">
  • 把宏單獨抽取出來,封裝成html文件,其它模板中導入使用,文件名可以自定義macro.html
{% macro function(type='text', name='', value='') %}
<input type="{{type}}" name="{{name}}"
value="{{value}}" class="form-control">{% endmacro %}
  • 在其它模板文件中先導入,再調用
{% import 'macro.html' as func %}
{% func.function() %}

代碼演練

  • 使用宏之前代碼
<form><label>用戶名:</label><input type="text" name="username"><br/><label>身份證號:</label><input type="text" name="idcard"><br/><label>密碼:</label><input type="password" name="password"><br/><label>確認密碼:</label><input type="password" name="password2"><br/><input type="submit" value="注冊">
</form>
  • 定義宏
{#定義宏,相當于定義一個函數,在使用的時候直接調用該宏,傳入不同的參數就可以了#}
{% macro input(label="", type="text", name="", value="") %}
<label>{{ label }}</label><input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}
  • 使用宏
<form>{{ input("用戶名:", name="username") }}<br/>{{ input("身份證號:", name="idcard") }}<br/>{{ input("密碼:", type="password", name="password") }}<br/>{{ input("確認密碼:", type="password", name="password2") }}<br/>{{ input(type="submit", value="注冊") }}
</form>

模板繼承

模板繼承是為了重用模板中的公共內容。一般Web開發中,繼承主要使用在網站的頂部菜單、底部。這些內容可以定義在父模板中,子模板直接繼承,而不需要重復書寫。

  • 標簽定義的內容
{% block top %} {% endblock %}
  • 相當于在父模板中挖個坑,當子模板繼承父模板時,可以進行填充。
  • 子模板使用 extends 指令聲明這個模板繼承自哪個模板
  • 父模板中定義的塊在子模板中被重新定義,在子模板中調用父模板的內容可以使用super()

父模板

  • base.html
{% block top %}頂部菜單
{% endblock top %}{% block content %}
{% endblock content %}{% block bottom %}底部
{% endblock bottom %}

子模板

  • extends指令聲明這個模板繼承自哪
{% extends 'base.html' %}
{% block content %}需要填充的內容
{% endblock content %}
  • 模板繼承使用時注意點:

    • 不支持多繼承
    • 為了便于閱讀,在子模板中使用extends時,盡量寫在模板的第一行。
    • 不能在一個模板文件中定義多個相同名字的block標簽。
    • 當在頁面中使用多個block標簽時,建議給結束標簽起個名字,當多個block嵌套時,閱讀性更好。

未完待續 下一期下一章

全套筆記直接地址: 請移步這里

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/news/162676.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/162676.shtml
英文地址,請注明出處:http://en.pswp.cn/news/162676.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

nvm切換版本之后npm用不了

原因是 nvm只給你安了對應的node沒給你安裝對應的node版本的npm 解決辦法如下 1找到你安裝的node版本號 然后去官網下載對應的版本包 這個網址就是node官網的版本列表 Index of /download/release/ 2下載后解壓 把根目錄這倆復制到自己的nvm安裝目錄下 還有那個node_modul…

Java【XML 配置文件解析】

前言 最近考試周忙得要死&#xff0c;但我卻不緊不慢&#xff0c;還有三天復習時間&#xff0c;考試科目幾乎都還沒學呢。今天更新一個算是工具類-XML文件的解析&#xff0c;感覺還是挺有用的&#xff0c;之后可以融進自己的項目里。 XML 配置文件解析 0、導入依賴 有點像我…

海康攝像頭ip地址設置方法

海康攝像頭是當前市場上非常受歡迎的一種監控設備&#xff0c;其可以在各種場合下發揮出極佳的作用。不過&#xff0c;對于初次使用該設備的人來說&#xff0c;設置其ip地址往往比較困難。虎觀代理小二二將會詳細介紹海康攝像頭ip地址設置的具體步驟&#xff0c;幫助大家輕松解…

PS右邊的圖層窗口沒有顯示出來?

問題描述&#xff1a;PS右邊的圖層窗口沒有顯示出來&#xff1f; 解決步驟&#xff1a; 鍵盤F7快捷鍵即可調出來。

企業軟件定制開發的優勢|app小程序網站搭建

企業軟件定制開發的優勢|app小程序網站搭建 企業軟件定制開發是一種根據企業特定需求開發定制化軟件的服務。相比于購買現成的軟件產品&#xff0c;企業軟件定制開發具有許多優勢。 1.企業軟件定制開發可以滿足企業獨特需求。每個企業都有自己獨特的業務流程和需求&#xff0c;…

在 Redis 中使用 JSON 文檔:命令行界面(CLI)和 Navicat 集成

Redis&#xff0c;因其極高的性能而聞名&#xff0c;是一款多功能的 NoSQL 數據庫&#xff0c;擅長處理鍵值對。雖然 Redis主要用于處理簡單數據結構&#xff0c;但是同樣支持更多復雜的數據類型&#xff0c;如列表、集合甚至是 JSON 文件。在本文&#xff0c;我們將深入到 Red…

SAP LU04記賬更改通知單創建轉儲單報錯:L3094 記帳修改沒有份存在

解決辦法&#xff1a; 使用事務碼LU02&#xff0c;修改過賬更改狀態&#xff0c;將過賬更改狀態改為U&#xff0c;強制關閉 1. LU04 查找記賬更改通知單號 2. 事務碼LU02修改狀態 這個時候再用LU04去查看的時候&#xff0c;就不會再顯示了

技術短視頻賬號矩陣seo系統--源頭開發---saas工具

專注短視頻賬號矩陣系統源頭開發---saas營銷化工具&#xff0c;目前我們作為一家純技術開發團隊目前已經專注打磨開發這套系統企業版/線下版兩個版本的saas營銷拓客工具已經3年了&#xff0c;本套系統邏輯主要是從ai智能批量剪輯、賬號矩陣全托管發布、私信觸單收錄、文案ai智能…

網絡安全等級保護2.0國家標準

等級保護2.0標準體系主要標準如下&#xff1a;1.網絡安全等級保護條例2.計算機信息系統安全保護等級劃分準則3.網絡安全等級保護實施指南4.網絡安全等級保護定級指南5.網絡安全等級保護基本要求6.網絡安全等級保護設計技術要求7.網絡安全等級保護測評要求8.網絡安全等級保護測評…

【AGC】云存儲服務端使用方法

【集成準備】 1、Python環境配置 下載Python和PyCharm并安裝。 ? 使用安裝的python本身作為解釋器。 ? 安裝AGC Python SDK。 ?云存儲包安裝完成。 ? 2、AGC環境配置 在AGC創建項目和應用 ? 開通云存儲服務。 返回項目設置界面&#xff0c;選擇Server SDK 頁簽…

雙系統Ubuntu-22.04.3安裝編譯kaldi

Ubuntu物理內存要求85-100G以上&#xff0c;運行內存5-6G以上&#xff08;如果第一次安裝的Ubuntu物理內存不夠&#xff0c;請勿進行擴容&#xff0c;擴容易出現黑屏、藍屏、死機的情況&#xff0c;應該卸載Ubuntu重新安裝&#xff0c;在安裝過程中進行內存分配&#xff1b;運行…

4.22每日一題(累次積分的計算:交換次序)

注&#xff1a;因為 是積不出的函數&#xff0c;所以先不用算&#xff0c;最后發現&#xff0c;出現dx與dy可以相互抵消&#xff0c;即可算出答案

為企業解決設備全生命周期需求,凌雄科技凸顯DaaS增長價值

企業成長離不開投資&#xff0c;但毫無疑問的是&#xff0c;投資最有價值的部分在業務。相比之下&#xff0c;諸如辦公設備之類的固定資產投資&#xff0c;很容易變成企業現金流的吞噬者。從購買、運維到保養、折舊、回收&#xff0c;現代企業在越來越大的辦公設備規模面前&…

工具 | docker刪除不使用的容器

工具 | docker刪除不使用的容器 Docker 清理命令

數據庫|TiDB v7.1.0 資源管控功能是如何降低運維難度和成本

目錄 一、前言 二、資源管控流程圖 三、資源管控 (Resource Control)測試 1&#xff09;測試集群環境 2&#xff09;Request Unit (RU) 概念 3&#xff09;資源管控參數 4&#xff09;評估實際負載所需容量 4.1 根據實際負載估算容量 方法一 or: 方法二 4.2 基于硬件…

鴻蒙原生應用/元服務開發-AGC分發如何配置簽名信息

使用制作的私鑰&#xff08;.p12&#xff09;文件、在AGC申請的證書文件和Profile&#xff08;.p7b&#xff09;文件&#xff0c;在DevEco Studio配置工程的簽名信息&#xff0c;以構建攜帶發布簽名信息的APP。 1.打開DevEco Studio&#xff0c;菜單選擇“File > Project S…

va-Q-tec實現溫度敏感產品運輸過程質量控制溫控無憂

摘要&#xff1a;溫度敏感產品運輸對供應鏈全流程的溫度質量要求較高&#xff0c;往往需要借助特殊的溫濕度監測技術產品。va-Q-tec與虹科Comet合作&#xff0c;采用虹科Comet的U系列溫度記錄儀&#xff0c;為集裝箱運輸過程提供完整的溫控包裝解決方案。 一、客戶背景 va-Q-…

鈷電解液中凈化除鎳除銅樹脂

#鈷電解液中凈化除鎳除銅樹脂 鈷是生產各種合金及電池不可或缺的原材料&#xff0c;鈷資源供給主要來自于大型銅礦和鎳礦的伴生開采&#xff0c;鈷的主要應用領域為動力電池、3C消費電池、各種耐熱合金、硬質合金、防腐合金、磁性合金及各種鈷鹽等。其中&#xff0c;電池領域是…

【洛谷算法題】P5714-肥胖問題【入門2分支結構】

&#x1f468;?&#x1f4bb;博客主頁&#xff1a;花無缺 歡迎 點贊&#x1f44d; 收藏? 留言&#x1f4dd; 加關注?! 本文由 花無缺 原創 收錄于專欄 【洛谷算法題】 文章目錄 【洛谷算法題】P5714-肥胖問題【入門2分支結構】&#x1f30f;題目描述&#x1f30f;輸入格式&a…

給項目快速接入鏈路追蹤

為什么需要鏈路追蹤&#xff1f; 我們程序員在日常工作中&#xff0c;最常做事情之一就是修bug了。如果程序只是運行在單機上&#xff0c;我們最常用的方式就是在程序上打日志&#xff0c;然后程序運行的過程中將日志輸出到文件上&#xff0c;然后我們根據日志去推斷程序是哪一…