舉例html
Flask Python代碼json
from flask import Flask, render_template, redirect, request app = Flask(__name__) STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'} STUDENT_LIST = [ {'name': 'Old', 'age': 38, 'gender': '中'}, {'name': 'Boy', 'age': 73, 'gender': '男'}, {'name': 'EDU', 'age': 84, 'gender': '女'} ] STUDENT_DICT = { 'a': {'name': 'Old', 'age': 38, 'gender': '中'}, 'b': {'name': 'Boy', 'age': 73, 'gender': '男'}, 'c': {'name': 'EDU', 'age': 84, 'gender': '女'}, } @app.route("/detail") def detail(): print(url_for("detail")) return render_template("detail.html", **STUDENT) @app.route("/detail_list", ) def detail_list(): return render_template("detail_list.html", stu_list=STUDENT_LIST) @app.route("/detail_dict") def detail_dict(): return render_template("detail_dict.html", stu_dict=STUDENT_DICT)
detail.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {{ stu }} <table border="1px"> <tr> <td>name</td> <td>age</td> <td>gender</td> </tr> <tr> <td>{{ name }}</td> <td>{{ age }}</td> <td>{{ gender }}</td> </tr> </table> </body> </html>
detail_list.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {{ stu_list }} <table border="1px"> <tr> <td>name</td> <td>age</td> <td>gender</td> </tr> {% for stu in stu_list %} {% if stu.name != "Old" %} {% if stu.age != 73 %} <tr> <td>{{ stu.name }}</td> <td>{{ stu.get("age") }}</td> <td>{{ stu["gender"] }}</td> </tr> {% endif %} {% endif %} {% endfor %} </table> </body> </html>
detail_dict.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {{ stu_dict }} <table border="1px"> <tr> <td>id</td> <td>name</td> <td>age</td> <td>gender</td> </tr> {% for stu_key,stu_value in stu_dict.items() %} <tr> <td>{{ stu_key }}</td> <td>{{ stu_value.get("name") }}</td> <td>{{ stu_value.age }}</td> <td>{{ stu_value.gender }}</td> </tr> {% endfor %} </table> </body> </html>
1.最經常使用的是變量,由Flask渲染模板時傳過來,好比name 也能夠是任意一種Python基礎類型,好比字符串{{stu_list}},用引號括起;或者數值,列表,元祖,字典,布爾值。直接顯示基礎類型沒啥意義,通常配合其餘表達式一塊兒用 2.運算。包括算數運算,如{{ 2 + 3 }};比較運算,如{{ 2 > 1 }};邏輯運算,如{{ False and True }} 3.過濾器|和測試器is 4.函數調用,如{{ current_time() }};數組下標操做,如{{ arr[1] }} in操做符,如{{ 1 in [1,2,3] }} 5.字符串鏈接符~,做用同Python中的+同樣,如{{ "Hello " ~ name ~ "!" }}
Jinja2的控制語句主要就是條件控制語句if,和循環控制語句for,語法相似於Python if-else: {% if name and name == 'admin' %} <h1>This is admin console</h1> {% elif name %} <h1>Welcome {{ name }}!</h1> {% else %} <h1>Please login</h1> {% endif %} for: {% for stu in stu_list%} {{ stu }} {% endfor %}
<body> {# 當變量未定義時,顯示默認字符串,能夠縮寫爲d #} <p>{{ name | default('No name', true) }}</p> {# 單詞首字母大寫 #} <p>{{ 'hello world' | capitalize }}</p> {# 單詞全小寫 #} <p>{{ 'XML' | lower }}</p> {# 去除字符串先後的空白字符 #} <p>{{ ' hello ' | trim }}</p> {# 字符串反轉,返回"olleh" #} <p>{{ 'hello' | reverse }}</p> {# 格式化輸出,返回"Number is 99" #} <p>{{ '%s is %d' | format("Number", 99) }}</p> {# 關閉HTML自動轉義 #} <p>{{ '<em>name</em>' | safe }}</p> {% autoescape false %} {# HTML轉義,即便autoescape關了也轉義,能夠縮寫爲e #} <p>{{ '<em>name</em>' | escape }}</p> {% endautoescape %} </body>
{# 四捨五入取整,返回13.0 #} <p>{{ 12.98 | round }}</p> {# 向下截取到小數點後2位,返回12.88 #} <p>{{ 12.8888 | round(2, 'floor') }}</p> {# 絕對值,返回12 #} <p>{{ -12 | abs }}</p>
# 取第一個元素 #} <p>{{ [1,2,3] | first }}</p> {# 取最後一個元素 #} <p>{{ [1,2,3] | last }}</p> {# 返回列表長度,能夠寫爲count #} <p>{{ [1,2,3,4,5] | length }}</p> {# 列表求和 #} <p>{{ [1,2,3,4,5] | sum }}</p> {# 列表排序,默認爲升序 #} <p>{{ [3,2,1,5,4] | sort }}</p> {# 合併爲字符串,返回"1 | 2 | 3 | 4 | 5" #} <p>{{ [1,2,3,4,5] | join(' | ') }}</p> {# 列表中全部元素都全大寫。這裏能夠用upper,lower,但capitalize無效 #} <p>{{ ['alex','bob','ada'] | upper }}</p>
{% set users=[{'name':'Tom','gender':'M','age':20}, {'name':'John','gender':'M','age':18}, {'name':'Mary','gender':'F','age':24}, {'name':'Bob','gender':'M','age':31}, {'name':'Lisa','gender':'F','age':19}] %} {# 按指定字段排序,這裏設reverse爲true使其按降序排 #} <ul> {% for user in users | sort(attribute='age', reverse=true) %} <li>{{ user.name }}, {{ user.age }}</li> {% endfor %} </ul> {# 列表分組,每組是一個子列表,組名就是分組項的值 #} <ul> {% for group in users|groupby('gender') %} <li>{{ group.grouper }}<ul> {% for user in group.list %} <li>{{ user.name }}</li> {% endfor %}</ul></li> {% endfor %} </ul> {# 取字典中的某一項組成列表,再將其鏈接起來 #} <p>{{ users | map(attribute='name') | join(', ') }}</p>
# 第一種方式 def get_even_list(l): return l[::2] # 函數的第一個參數是過濾器函數,第二個參數是過濾器名稱 app.add_template_filter(get_even_list, 'even_filter') # 第二種方式 @app.template_filter() # 過濾器函數 def is_even(num): if num % 2 == 0: return "even number" else: return "odd number"
使用flask
<p>{{ [1,2,3,4,5] | even_filter }}</p> <p>{{ 2 | is_even }}</p>
測試器老是返回一個布爾值,它能夠用來測試一個變量或者表達式,使用」is」關鍵字來進行測試。api
{% set name='ab' %} {% if name is lower %} <h2>"{{ name }}" are all lower case.</h2> {% endif %}
測試器本質上也是一個函數,它的第一個參數就是待測試的變量,在模板中使用時能夠省略去。若是它有第二個參數,數組
模板中就必須傳進去。測試器函數返回的必須是一個布爾值,這樣才能夠用來給if語句做判斷。app
舉例函數
{# 檢查變量是否被定義,也能夠用undefined檢查是否未被定義 #} {% if name is defined %} <p>Name is: {{ name }}</p> {% endif %} {# 檢查是否全部字符都是大寫 #} {% if name is upper %} <h2>"{{ name }}" are all upper case.</h2> {% endif %} {# 檢查變量是否爲空 #} {% if name is none %} <h2>Variable is none.</h2> {% endif %} {# 檢查變量是否爲字符串,也能夠用number檢查是否爲數值 #} {% if name is string %} <h2>{{ name }} is a string.</h2> {% endif %} {# 檢查數值是不是偶數,也能夠用odd檢查是否爲奇數 #} {% if 2 is even %} <h2>Variable is an even number.</h2> {% endif %} {# 檢查變量是否可被迭代循環,也能夠用sequence檢查是不是序列 #} {% if [1,2,3] is iterable %} <h2>Variable is iterable.</h2> {% endif %} {# 檢查變量是不是字典 #} {% if {'name':'test'} is mapping %} <h2>Variable is dict.</h2> {% endif %}
官方文檔post
https://jinja.palletsprojects.com/en/master/templates/#builtin-tests測試
定義網站
# 自定義測試器 # 第一種方式 import re def test_tel(tel_num): tel_re = r'\d{11}' return re.match(tel_re,tel_num) app.add_template_test(test_tel,"is_tel") # 第二種方式 @app.template_test('start_with') def start_with(str, suffix): return str.lower().startswith(suffix.lower())
使用
{% set tel = '18910171111' %} {% if tel is is_tel %} <h2>{{ tel }} is mobile phone</h2> {% endif %} {% set name = 'Hello world' %} {% if name is start_with 'hello' %} <h2>"{{ name }}" start_with "hello"</h2> {% endif %}
{# 全局函數range()的做用同Python裏的同樣,返回指定範圍內的數值序列。三個參數分別是開始值,結束值(不包含),間隔。 若是隻傳兩個參數,那間隔默認爲1;若是隻傳1個參數,那開始值默認爲0。 #} <ul> {% for num in range(10,20,2) %} <li>Number is "{{ num }}"</li> {% endfor %} </ul> {# dict()函數,方便生成字典型變量 #} {% set user = dict(name='Joh',age=22) %} <p>{{ user | tojson | safe }}</p> {# 顯示 '{"age": 22, "name": "Joh"}' #} {# joiner()函數,它能夠初始化爲一個分隔符,而後第一次調用時返回空字符串,之後再調用則返回分隔符 #} {% set sep = joiner("|") %} {% for val in range(5) %} {{ sep() }} <span>{{ val }}</span> {% endfor %} {# 顯示 "0 | 1 | 2 | 3 | 4" #} {# cycler()函數,在給定的序列中輪循 #} {% set cycle = cycler('odd', 'even') %} <ul> {% for num in range(10, 20, 2) %} <li class="{{ cycle.next() }}">Number is "{{ num }}", next line is "{{ cycle.current }}" line.</li> {% endfor %} {# next(),返回當前值,並往下一個值輪循 reset(),重置爲第一個值 current,當前輪循到的值 #} </ul>
官方文檔
https://jinja.palletsprojects.com/en/master/templates/#list-of-global-functions
定義
# 自定義全局函數 # 第一種方式 @app.template_global() def add_sum(*args): return sum(args) # 第二種方式 import time def current_time(timeFormat="%b %d, %Y - %H:%M:%S"): return time.strftime(timeFormat) app.add_template_global(current_time, 'current_time')
使用
<p>{{ add_sum(1,2,3,4,5) }}</p> <p>Current Time is: {{ current_time() }}</p> <p>Current Day is: {{ current_time("%Y-%m-%d") }}</p>
通常咱們的網站雖然頁面多,可是不少部分是重用的,好比頁首,頁腳,導航欄之類的。對於每一個頁面,都要寫這些代碼,很麻煩。
Flask的Jinja2模板支持模板繼承功能,省去了這些重複代碼。
template:
<body> 你好,template1 {% block template1 %} {% endblock %} 你好,template2 {% block template2 %} {% endblock %} 你好,template {% block template %} {% endblock %} </body>
extend:
{% extends "he.html" %} {% block template %} <h1>yuan</h1> {% endblock %} {% block template1 %} <h1>alex</h1> {% endblock %} {% block template2 %} <h1>wu</h1> {% include "aaa.html" %} {% endblock %}