摘要:FastAPI 實際上是為構建 API 和微服務而設計的,它可用于構建使用 Jinja 提供 HTML 服務的 Web 應用程式,
本文分享自華為云社區《FastAPI 快速開發 Web API 專案: 模板和 Jinja 介紹》,作者:宇宙之一粟,
什么是 Jinja
模板是全堆疊 Web 開發的重要組成部分,使用 Jinja,您可以構建豐富的模板,為您的 Python Web 應用程式的前端提供支持,
Jinja 是一個用 Python 撰寫的模板引擎,旨在幫助 API 回應的渲染程序,在每種模板語言中,都有變數被替換為實際傳遞給它們的值,當模板被渲染時,有控制模板邏輯的標簽,
安裝 jinja2:
pipenv install jinja2
安裝成功后:
Jinja 模板只是一個文本檔案, Jinja 可以生成任何基于文本的格式(HTML、XML、CSV、LaTeX 等), Jinja 模板不需要有特定的擴展名:.html、.xml 或任何其他擴展名都可以,
關于模版的擴展名:任何檔案都可以作為模板加載,無論檔案擴展名如何,添加 .jinja 擴展名,如 user.html.jinja 可能會使某些 IDE 或編輯器插件更容易,但這不是必需的,自動轉義可以基于檔案擴展名應用,因此在這種情況下您需要考慮額外的后綴,
識別模板的另一個很好的啟發式方法是它們位于模板 templates 檔案夾中,而不管擴展名是什么,這是專案的常見布局,
Jinja 模板引擎使用花括號 {} 來區分其運算式和語法與常規 HTML、文本和模板檔案中的任何其他變數,{{}} 語法稱為變數塊,{% %} 語法包含控制結構,如 if/else 、回圈和宏,Jinja 模板語言中使用的三種常見語法塊包括以下內容:
- {% ... %}:這種語法用于控制結構等陳述句,
- {{ todo.item }}:這個語法用于列印出傳遞給它的運算式的值,
- {# Test #}: 這種語法在寫評論時使用,不在網頁上顯示,
Jinja2 是一種流行的模板語言,被 Flask、Bottle、Pelican 使用,也可被 Django 使用,
渲染第一個 Jinja 模板
匯入 Jinja 后,您可以繼續加載和渲染您的第一個模板:
>>> import jinja2 >>> environment = jinja2.Environment() >>> template = environment.from_string("Hello, {{ name }}!") >>> template.render(name="Yuzhou1su") 'Hello, Yuzhou1su!' >>>
Jinja 的核心組件是 Environment() 類,在此示例中,您創建了一個不帶任何引數的 Jinja 環境,稍后您將更改 Environment 的引數以自定義您的環境,在這里,您正在創建一個普通環境,您可以在其中加載字串 Hello, {{ name }}! 作為模板,
這個例子顯示了你在使用 Jinja 時通常會執行的兩個重要步驟:
- 加載模板:加載包含占位符變數的源,默認情況下,它們包含在一對大括號 {{ }} 中,
- 渲染模板:用內容填充占位符,您可以提供字典或關鍵字引數作為背景關系,在本例中,您已經填充了占位符,因此 Hello, Yuzhou1su! 作為輸出,
使用外部檔案作為模板
與上述方式同理,我們可以使用外部檔案作為我們的模版來源,在我們的專案中創建一個新檔案夾,在作業目錄中,創建一個名為 templates/ 的檔案夾,
然后,您可以在 “template” 目錄中創建 index.html 模板檔案,并使用 Jinja2 語法來呈現它們,例如,在template/index.html 中寫入如下內容:
<!DOCTYPE html> <html> <head> <title>Welcome</title> <link href=https://www.cnblogs.com/huaweiyun/archive/2023/04/25/"{{ url_for('static', path='/styles.css') }}" rel="stylesheet"> </head> <body> <h1>Hello, {{ name }}</h1> </body> </html>
然后回到我們的 main.py 中:
from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates app = FastAPI() app.mount("/static", StaticFiles(directory="static"), name="static") templates = Jinja2Templates(directory="templates") @app.get("/{name}") async def home(request: Request, name: str): return templates.TemplateResponse("index.html", { "request": request, "name": name })
整個檔案的目錄結構如下:
啟動 FastAPI 服務 uvicorn main:app --reload --port 8888, 然后另外打開一個終端,執行 curl 127.0.0.1:8888/Yuzhou1su 命令,可以看到如下 name 被渲染出來的結果:
通過瀏覽器訪問這個 http://127.0.0.1:8888/Yuzhou1su,還能看到 css 渲染的顏色:
Jinja 模板變數可以是任何 Python 型別或物件,只要它們可以轉換為字串,可以將模型、串列或字典型別傳遞到模板中,并通過將這些屬性放置在先前列出的第二個塊中來顯示其屬性,在下一節中,我們將看一下過濾器,過濾器是每個模板引擎的重要組成部分,在 Jinja 中,過濾器使我們能夠執行某些函式,例如從串列中連接值和檢索物件的長度,等等,Jinja 中常用的功能:變數、過濾器、if 陳述句、回圈、宏和模板繼承,
變數
模板變數由傳遞給模板的背景關系字典定義,
在模板中,只要應用程式傳遞了變數,您就可以隨意操作這些變數,變數可能還具有您可以訪問的屬性或元素,變數具有哪些屬性取決于提供該變數的應用程式,
除了標準的 Python __getitem__ “下標”語法( [] )之外,您還可以使用點(. )來訪問變數的屬性,
以下行執行相同的操作:
{{ foo.bar }} {{ foo['bar'] }}
Filters
盡管 Python 和 Jinja 的語法非常相似,但是像連接字串、將字串的第一個字符設定為大寫等修改操作不能使用Python 的語法在 Jinja 中完成,因此,為了執行這樣的修改操作,我們在 Jinja 中使用過濾器,
變數可以被過濾器修改,過濾器與變數用管道符號(|)分隔,并且可以在括號中包含可選引數,可以鏈接多個過濾器,一個過濾器的輸出應用于下一個,過濾器的定義格式如下:
{{ variable | filter_name(*args) }}
不加引數的過濾器:
{{ variable | filter_name }}
{{ name|striptags|title }}
default 過濾器: 如果該值未定義,它將回傳傳遞的默認值,否則回傳變數的值:
{{ my_variable | default('my_variable is not defined') }}
escape 過濾器: 這個過濾器用于渲染原始 HTML 輸出:將字串 s 中的字符 & < > ' ” 轉換為 HTML 安全序列,如果您需要在 HTML 中顯示可能包含此類字符的文本,請使用此選項,將回傳值標記為標記字串,
{{ "<title>Todo Application</title>" | escape }}
<title>Todo Application</title>
型別轉換過濾器: 這些過濾器包括 int 和 float 過濾器,用于從一種資料型別轉換到另一種資料型別:
{{ 3.142 | int }}
3
{{ 20 | float }}
20.0
join 過濾器:join(*value*, *d=u''* , *attribute=None*)回傳一個字串,它是序列中字串的串聯,元素之間的分隔符默認為空字串,您可以使用可選引數定義它:
{{ [1, 2, 3] | join('|') }}
-> 1|2|3
{{ [1, 2, 3] | join }}
-> 123
也可以連接物件的某些屬性:
{{ users|join(', ', attribute='username') }}
長度 filter: 這個過濾器回傳一個序列或集合的長度,它的作用與 Python 中 len() 函式的作用相同:
Todo count: {{ todos | length }}
Todo count: 4
if 條件
Jinja 中 if 陳述句的用法與 Python 中的用法類似,在 {% %} 控制塊中使用,讓我們看一個例子:
{% if todos %}
<ul>
{% for todo in todos %}
<li>{{ todo.name|e }}</li>
{% endfor %}
</ul>
{% endif %}
Loop 條件
我們也可以在Jinja中對變數進行迭代,這可以是一個串列或一個一般的函式、 比如說下面這個,例如
{% for todo in todos %}
<li>{{ todo.name|e }}</li>
{% endfor %}
你可以在 for 回圈中訪問特殊的變數,比如 loop.index ,它給出了當前迭代的索引,
宏
宏可與常規編程語言中的函式相媲美,它們有助于將常用的習語放入可重用的函式中,以免重復自己(“DRY” 原則),
{% macro input(name, value=https://www.cnblogs.com/huaweiyun/archive/2023/04/25/'', type='text', size=20) %}
<div class="form">
<input type="{{ type }}" name="{{ name }}"
value="{{ value|escape }}" size="{{ size }}">
</div>
{% endmacro %}
現在,為了在你的表單中快速創建一個輸入,呼叫了這個宏:
{{ input('item') }}
渲染完成后,將會回傳:
<div class="form"> <input type="text" name="item" value=https://www.cnblogs.com/huaweiyun/archive/2023/04/25/"" size="20" /> </div>
FastAPI 中的 Jinja
FastAPI 實際上是為構建 API 和微服務而設計的,它可用于構建使用 Jinja 提供 HTML 服務的 Web 應用程式,但這并不是它真正優化的目的,
如果您想構建一個在服務器上呈現大量 HTML 的大型網站,Django 可能是更好的選擇,
但是,如果您正在使用 React、Angular 或 Vue 等前端框架構建現代網站,那么從 FastAPI 獲取資料是一個不錯的選擇,
參考鏈接:
- Templates
- The Ultimate FastAPI Tutorial Part 6 - Serving HTML with Jinja Templates
- Simple ToDo App in FastAPI with Jinja2 Template
- Primer on Jinja Templating
- Template Designer Documentation
點擊關注,第一時間了解華為云新鮮技術~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/551231.html
標籤:其他
上一篇:了解一下XSS
下一篇:返回列表
