1. 程式人生 > >Flask框架(三)-Jinja2模板

Flask框架(三)-Jinja2模板

Jinja2模板引擎簡介

Jinja2模板概述

用來展示資料的html頁面,這個過程也通常稱為渲染,屬於Jinja2的功能 使用模板的好處:

檢視函式只負責業務邏輯和資料處理(業務邏輯方面)

而模板則取到檢視函式的資料結果進行展示(檢視展示方面)

程式碼結構清晰,耦合度低

二.Jinja2特點

Jinja2:是 Python 下一個被廣泛應用的模板引擎,是由Python實現的模板語言,他的設計思想來源於 Django 的模板引擎,並擴充套件了其語法和一系列強大的功能,其是Flask內建的模板語言。

模板語言:是一種被設計來自動生成文件的簡單文字格式,在模板語言中,一般都會把一些變數傳給模板,替換模板的特定位置上預先定義好的佔位變數名。

使用render_template函式封裝模板引擎

模板的使用

獲取變數值:

    <h1>整數:{ {number} }</h1>

    <h1>元祖:{ {tuple[0]} }</h1>

    <h1>列表:{ { list[0] } }</h1>

    <h1>字典:{ { dict['key'] } }</h1>

分支語句if

變數

描述

loop.index

當前迭代的索引(從1開始)

loop.index0

當前迭代的索引(從0開始)

loop.first

是否是第一次迭代,返回True/False

loop.last

是否是最後一次迭代,返回True/False

loop.length

序列的長度

{ % if 條件 % }

    語句1

 { % else % }    

    語句2

{ % endif % }

for迴圈

{% for 變數  in 容器 %}

    語句

{% endfor%}

註釋

{# 註釋內容 #}

使用函式: render_template('模板檔名',key=value)

傳遞給html檔案{{number}}中的number就是key的值。

app = Flask(__name__) #預設省略了三個引數,static_url_path, static_folder, template_folders

static_url_path靜態檔案的地址字首,寫成什麼,訪問靜態檔案時,就要在前面加上這

static_folder靜態檔案所在檔案的名字,預設是static,可以不用填

template_folder模板所在資料夾的名字

response = render_template("file01moban.html")

渲染:通過render_teplate將這個模板html檔案給渲染。

自帶過濾器

過濾器的本質就是函式。

字串

* 使用格式:{{ 字串 | 字串過濾器 }}

<p>{{ '<em>hello</em>' | safe }}</p> 禁用轉義

<p>{{ 'hello' | capitalize }}</p> 首字母大寫

<p>{{ 'HELLO' | lower }}</p> 全部轉為小寫

<p>{{ 'hello' | upper }}</p> 全部轉為大寫

<p>{{ 'hello' | title }}</p> 把值中的每個單詞的首字母都轉成大寫

<p>{{ 'olleh' | reverse }}</p> 字串反轉

<p>{{ '%s is %d' | format('name',17) }}</p> 格式化輸出

<p>{{ '<em>hello</em>' | striptags }}</p> 刪除標籤

列表

* 使用格式:{{ 列表 | 列表過濾器 }}

<p>{{ [1,2,3,4,5,6] | first }}</p>   取第一個元素

<p>{{ [1,2,3,4,5,6] | last }}</p>   取最後一個元素

<p>{{ [1,2,3,4,5,6] | length }}</p> 獲取列表長度

<p>{{ [1,2,3,4,5,6] | sum }}</p>  列表求和

<p>{{ [6,2,3,1,5,4] | sort }}</p>   列表排序

語句塊操作

{% filter upper %}

    #一大堆文字#

{% endfilter %}

鏈式呼叫

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

自定過濾器兩種方式:

1.先定義函式,後新增到過濾器列表中

def my_filter():

    pass

app.add_template_filter(函式名,過濾器名稱)

2.定義函式的同時,就是用過濾器列表裝飾

@app.template_filter(過濾器名稱)

def my_filter():

pass

模板程式碼複用

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

多個模板具有完全相同的頂部和底部內容

多個模板中具有相同的模板程式碼內容,但是內容中部分值不一樣

多個模板中具有完全相同的 html 程式碼塊內容

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

巨集

{# 定義巨集 #}

    {% macro input(巨集的名稱)(name) %}

        <h3>{{ name }}</h3>

        <h3>荒於嬉</h3>

        <h3>行成於思毀於隨</h3>

    {% endmacro %}

    {# 呼叫巨集 #}

    {{ input相當於呼叫input("業精於勤"(傳入的name引數) }}

    {# 使用其他檔案巨集 #}

    {% import 'file07macro.html' as other %}

{{ other.input("使用者名稱","123456") }}

繼承

模板繼承: 使用的關鍵字是extends

格式: {% extends '父模板檔案'%}

注意點:

1.繼承一般頂格寫,繼承父類後子類內容無效

2.使用的全部都是父類內容

3.父類中編寫,所有子類共性內容

4.父類中需要留出'坑'(block),供子類去填充特有內容

5.重寫了父類模板內容之後,需要保留父類內容,使用super()

模板包含: 使用關鍵字include

格式: {% include '檔案' ignore missing%}

ignore missing: 如果包含的檔案不存在不會報錯

特點: 沒有辦法擴充套件內容,所以不夠靈活

父類的內容(在父類的正文內容裡填充內容是不會顯示的,需要在block之前寫內容)

{# 1.正文,留出位置,讓不同的子類去填充 #}

<h3>父類的標題</h3>

    {% block contentBlock %}

    {% endblock %}

    {# 2.底部,留出位置,填寫部分內容 #}

    {% block bottomBlock %}

        <div><a href="http://www.baidu.com">父類一下</a></div>

    {% endblock %}

子類的內容(不需要再設定html建立的相關屬性)

{% extends 'fu.html' %}

{# 1.填寫子類自己的正文內容 #}

{% block contentBlock %}

    <p>   每當我錯過一個女孩,我就向山上方塊磚,於是....就有了長城  </p>

{% endblock %}

{# 2.重寫,底部內容 #}

{% block bottomBlock %}

    {# 保留父類bottom裡面的內容 #}

    {{ super() }}

    <div><a href="http://www.jd.com">京東一下</a></div>

{% endblock %}

包含

{% include 'file09zi.html' ignore missing %}

特殊變數

<h3>config物件: {{ config }}</h3>

    <h3>request物件method: {{ request.method }}</h3>

    <h3>request物件url: {{ request.url }}</h3>

    <h3>url_for(): {{ url_for('hello_world') }}</h3>(返回的是路由路徑

py伺服器程式中:@app.route('/test/<int:token>')

    <h3>url_for(): {{ url_for('test',token=10) }}</h3>

get_flashed_messages():

消耗訊息佇列資料,指的是通過flash方法存進去的資料。

注意點:

內部的儲存依賴於了session,所以需要設定SECRET_KEY

每次獲取都會消耗掉佇列中的資料。

檢視函式中:flash(內容)

{%for message in get_flashed_messages()%}

    {{message}}

{%endfor%}

伺服器程式

app.config["SECRET_KEY"] = "fjdkfjkdjfkd"

@app.route('/')

def hello_world():

    flash("登陸成功")

    return render_template("file12flashed.html")

@app.route('/test')

def test():

    flash("登陸失敗")

return "test...."

html檔案程式

 {% for message in get_flashed_messages() %}

        <h3>{{ message }}</h3>

   {% endfor %}

csrf:跨站請求偽造

使用者未登出情況下訪問第三方網站,網站盜用了身份獲取cookie資訊然後偽裝成使用者傳送惡意請求。

防止CSRF攻擊

在後端響應cookie設定csrf_token的值,在form表單新增一個隱藏的欄位值也是csrf_token,使用者點選提交的時候講這兩個值就進行對比如果一樣就代表是正常的請求。(cookie和csrf_token攔截器的值和伺服器設定的相等)