Python中Flask模板的使用與高級(jí)技巧詳解
一、模板渲染基礎(chǔ)
1.1 為什么需要模板引擎
在Web開(kāi)發(fā)中,直接將HTML代碼寫在Python文件中會(huì)導(dǎo)致諸多問(wèn)題:
- 代碼難以維護(hù)
- 前后端耦合嚴(yán)重
- 無(wú)法復(fù)用HTML組件
- 缺乏邏輯控制能力
Flask內(nèi)置了Jinja2模板引擎,完美解決了這些問(wèn)題。
1.2 第一個(gè)模板渲染示例
首先創(chuàng)建項(xiàng)目結(jié)構(gòu):
myapp/
├── app.py
└── templates/
└── index.html
app.py內(nèi)容:
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): user = {'username': '張三', 'age': 25} posts = [ {'title': '第一篇', 'content': '內(nèi)容1'}, {'title': '第二篇', 'content': '內(nèi)容2'} ] return render_template('index.html', user=user, posts=posts) if __name__ == '__main__': app.run(debug=True)
templates/index.html內(nèi)容:
<!DOCTYPE html> <html> <head> <title>{{ user.username }}的主頁(yè)</title> </head> <body> <h1>歡迎, {{ user.username }}!</h1> <p>年齡: {{ user.age }}</p> <h2>文章列表</h2> <ul> {% for post in posts %} <li>{{ post.title }} - {{ post.content }}</li> {% endfor %} </ul> </body> </html>
1.3 模板渲染原理
render_template()函數(shù)的工作流程:
- 在templates目錄查找指定模板文件
- 解析模板中的變量和邏輯
- 將上下文變量傳入模板
- 生成最終HTML響應(yīng)
二、模板訪問(wèn)對(duì)象屬性
2.1 訪問(wèn)字典屬性
<p>用戶名: {{ user['username'] }}</p> <p>年齡: {{ user.get('age', 18) }}</p> <!-- 帶默認(rèn)值 -->
2.2 訪問(wèn)對(duì)象屬性
假設(shè)我們有一個(gè)User類:
class User: def __init__(self, username, email): self.username = username self.email = email
模板中可以這樣訪問(wèn):
<p>用戶名: {{ user.username }}</p> <p>郵箱: {{ user.email }}</p>
2.3 訪問(wèn)列表和元組
<p>第一篇文章: {{ posts[0].title }}</p> <p>最后一篇文章: {{ posts[-1].title }}</p>
2.4 特殊變量訪問(wèn)
<p>當(dāng)前時(shí)間: {{ config.DEBUG }}</p> <!-- 訪問(wèn)Flask配置 --> <p>請(qǐng)求方法: {{ request.method }}</p> <!-- 訪問(wèn)請(qǐng)求對(duì)象 --> <p>會(huì)話信息: {{ session.get('user_id') }}</p> <p>閃現(xiàn)消息: {{ get_flashed_messages() }}</p>
三、過(guò)濾器的使用
3.1 內(nèi)置過(guò)濾器大全
Jinja2提供了豐富的內(nèi)置過(guò)濾器:
<!-- 字符串處理 --> <p>{{ "hello"|capitalize }}</p> <!-- Hello --> <p>{{ "HELLO"|lower }}</p> <!-- hello --> <p>{{ "hello world"|title }}</p> <!-- Hello World --> <p>{{ "hello"|replace("e", "a") }}</p> <!-- hallo --> <!-- 列表處理 --> <p>{{ [1,2,3]|length }}</p> <!-- 3 --> <p>{{ [1,2,3]|first }}</p> <!-- 1 --> <p>{{ [1,2,3]|last }}</p> <!-- 3 --> <p>{{ [1,2,3]|join("|") }}</p> <!-- 1|2|3 --> <!-- 數(shù)值處理 --> <p>{{ 3.1415926|round(2) }}</p> <!-- 3.14 --> <p>{{ 1000|filesizeformat }}</p> <!-- 1000 Bytes --> <p>{{ 0.85|float }}</p> <!-- 0.85 --> <!-- 日期處理 --> <p>{{ user.create_time|datetimeformat }}</p> <p>{{ user.create_time|datetimeformat('%Y-%m-%d') }}</p> <!-- HTML處理 --> <p>{{ "<script>alert(1)</script>"|escape }}</p> <p>{{ "Markdown text"|markdown }}</p> <p>{{ "https://example.com"|urlencode }}</p>
3.2 自定義過(guò)濾器
在app.py中注冊(cè)自定義過(guò)濾器:
@app.template_filter('reverse') def reverse_filter(s): return s[::-1] @app.template_filter('format_phone') def format_phone(phone): return f"{phone[:3]}-{phone[3:7]}-{phone[7:]}"
模板中使用:
<p>{{ "hello"|reverse }}</p> <!-- olleh --> <p>{{ "13812345678"|format_phone }}</p> <!-- 138-1234-5678 -->
Flask模板高級(jí)技巧
1.控制語(yǔ)句
條件判斷
{% if user.age < 18 %} <p>未成年用戶</p> {% elif user.age > 60 %} <p>老年用戶</p> {% else %} <p>成年用戶</p> {% endif %}
循環(huán)語(yǔ)句
<table> <thead> <tr> <th>序號(hào)</th> <th>標(biāo)題</th> <th>內(nèi)容</th> </tr> </thead> <tbody> {% for post in posts %} <tr class="{{ loop.cycle('odd', 'even') }}"> <td>{{ loop.index }}</td> <td>{{ post.title }}</td> <td>{{ post.content }}</td> </tr> {% else %} <tr> <td colspan="3">暫無(wú)文章</td> </tr> {% endfor %} </tbody> </table>
循環(huán)變量說(shuō)明:
- loop.index: 當(dāng)前迭代次數(shù)(從1開(kāi)始)
- loop.index0: 當(dāng)前迭代次數(shù)(從0開(kāi)始)
- loop.revindex: 反向迭代次數(shù)
- loop.first: 是否第一次迭代
- loop.last: 是否最后一次迭代
- loop.length: 序列長(zhǎng)度
宏定義(模板函數(shù))
定義宏:
{% macro render_comment(comment) %} <div class="comment"> <p>{{ comment.author }} 說(shuō):</p> <blockquote>{{ comment.content }}</blockquote> </div> {% endmacro %}
使用宏:
{{ render_comment(comment) }} <!-- 導(dǎo)入其他模板中的宏 --> {% from 'macros.html' import render_comment %}
2.模板繼承
基礎(chǔ)模板(base.html)
<!DOCTYPE html> <html> <head> <title>{% block title %}默認(rèn)標(biāo)題{% endblock %}</title> {% block head %} <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" rel="external nofollow" > {% endblock %} </head> <body> <div class="container"> {% block content %} <h1>默認(rèn)內(nèi)容</h1> {% endblock %} </div> {% block footer %} <footer> <p>© 2023 My App</p> </footer> {% endblock %} </body> </html>
子模板繼承
{% extends "base.html" %} {% block title %}用戶主頁(yè) - {{ super() }}{% endblock %} {% block head %} {{ super() }} <style> .profile { color: blue; } </style> {% endblock %} {% block content %} <div class="profile"> <h1>{{ user.username }}的個(gè)人資料</h1> <p>年齡: {{ user.age }}</p> </div> {% endblock %} {% block footer %} <footer> <p>© 2023 用戶中心</p> </footer> {% endblock %}
包含其他模板
<!-- 包含頭部 --> {% include 'header.html' %} <!-- 帶參數(shù)包含 --> {% include 'user_card.html' with user=current_user %} <!-- 忽略缺失模板 --> {% include 'sidebar.html' ignore missing %}
3.加載靜態(tài)文件
靜態(tài)文件組織
標(biāo)準(zhǔn)項(xiàng)目結(jié)構(gòu):
myapp/
├── app.py
├── static/
│ ├── css/
│ ├── js/
│ └── images/
└── templates/
引用靜態(tài)文件
<!-- CSS文件 --> <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" rel="external nofollow" > <!-- JavaScript文件 --> <script src="{{ url_for('static', filename='js/main.js') }}"></script> <!-- 圖片 --> <img src="{{ url_for('static', filename='images/logo.png') }}" alt="Logo"> <!-- 使用緩存清除 --> <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css', v=1.0) }}" rel="external nofollow" >
靜態(tài)文件版本控制
在配置中添加版本號(hào):
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 3600 # 1小時(shí)緩存 app.config['STATIC_VERSION'] = '1.0.0'
模板中使用:
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}?v={{ config.STATIC_VERSION }}" rel="external nofollow" >
使用CDN資源
{% if config.CDN_ENABLED %} <script src="https://cdn.example.com/jquery/3.6.0.min.js"></script> {% else %} <script src="{{ url_for('static', filename='js/jquery.min.js') }}"></script> {% endif %}
以上就是Python中Flask模板的使用與高級(jí)技巧詳解的詳細(xì)內(nèi)容,更多關(guān)于Python Flask模板的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python 利用百度API進(jìn)行淘寶評(píng)論關(guān)鍵詞提取
這篇文章主要介紹了python 利用百度API進(jìn)行淘寶評(píng)論關(guān)鍵詞提取,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下2021-03-03python面試題之read、readline和readlines的區(qū)別詳解
當(dāng)python進(jìn)行文件的讀取會(huì)遇到三個(gè)不同的函數(shù),它們分別是read(),readline(),和readlines(),下面這篇文章主要給大家介紹了關(guān)于python面試題之read、readline和readlines區(qū)別的相關(guān)資料,需要的朋友可以參考下2022-07-07如何解決Python:報(bào)錯(cuò)[Errno 2]No such file or&nb
介紹了Python文件讀取操作時(shí)常見(jiàn)的錯(cuò)誤原因及解決方法,主要錯(cuò)誤原因包括路徑拼寫錯(cuò)誤、工作目錄與相對(duì)路徑不匹配以及文件不存在,解決方法有使用絕對(duì)路徑和動(dòng)態(tài)獲取腳本路徑,其他注意事項(xiàng)包括驗(yàn)證文件路徑與名稱、理解工作目錄與相對(duì)路徑2025-02-02python Tkinter實(shí)時(shí)顯示數(shù)據(jù)功能實(shí)現(xiàn)
這篇文章主要介紹了python Tkinter實(shí)時(shí)顯示數(shù)據(jù)功能實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07python調(diào)用百度AI接口實(shí)現(xiàn)人流量統(tǒng)計(jì)
這篇文章主要介紹了python調(diào)用百度AI接口實(shí)現(xiàn)人流量統(tǒng)計(jì),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02使用Python實(shí)現(xiàn)with結(jié)構(gòu)的@contextmanager方法詳解
這篇文章主要介紹了使用Python實(shí)現(xiàn)with結(jié)構(gòu)的@contextmanager方法詳解,這個(gè)結(jié)構(gòu)的好處,一個(gè)是簡(jiǎn)潔,一個(gè)是當(dāng)我們對(duì)文件操作的邏輯很長(zhǎng)的時(shí)候,不會(huì)因?yàn)橥岁P(guān)閉文件而造成不必要的錯(cuò)誤,需要的朋友可以參考下2023-07-07Python中if __name__ == "__main__"詳細(xì)解釋
這篇文章主要介紹了Python中if __name__ == "__main__"詳細(xì)解釋,需要的朋友可以參考下2014-10-10matplotlib之pyplot模塊之標(biāo)題(title()和suptitle())
這篇文章主要介紹了matplotlib之pyplot模塊之標(biāo)題(title()和suptitle()),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02Python生成器next方法和send方法區(qū)別詳解
這篇文章主要介紹了Python生成器next方法和send方法區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05