1. 程式人生 > >flask(二)之Jinja2模板與Flask-WTF

flask(二)之Jinja2模板與Flask-WTF

開始 識別 hone was http ike 集成 ros validate

01-文檔

官方文檔:http://docs.jinkan.org/docs/jinja2/

02-基本語義

Jinja2做構成的模板文件中,文本內容大致可以分成幾個種類。比如特殊文本(不進行轉義,比如HTML,XML格式的文本)、{{ }}表示的變量或者宏調用、{% %}表示邏輯控制,{# #}表示註釋,其中內容不被模板引擎轉義。

03-渲染模板

默認情況下,Flask在項目目錄中的templates子目錄中尋找模板。render_template()

from flask import Flask, render_template

app = Flask(__name__)

app.config.update({
    
DEBUG: True, TEMPLATES_AUTO_RELOAD: True, }) @app.route(/) def index(): return render_template("index.html") @app.route(/user/<name>) def user(name): return render_template(user.html, name=name) if __name__ == __main__: app.run()

04-變量

Jinja2能識別所有類型的變量,如:列表、字典和對象。

示例:

技術分享圖片

變量過濾器:

技術分享圖片

05-控制結構—宏

{% macro render_comment(comment) %}
    <li>{{ comment }}</li>
{% endmacro %}

<ul>
    {% for comment in comments %}
        {{ render_comment(comment) }}
    {% endfor %}
</ul>

為了重復使用宏,可以把宏保存在單獨的文件中,然後再需要使用的模板中導入:

{% import ‘macros.html‘ as macros %}

<ul> {% for comment in comments %} {{ render_comment(comment) }} {% endfor %} </ul>

需要在多處重復使用的模板代碼寫入單獨的文件,再引入所有的模板中,以避免重復:

{% include ‘common.html‘ %}

06-使用Flask-Bootstrap集成Bootstrap

# 安裝

pip install flask-bootstrap

初始化方式:

from flask_bootstrap Bootstrap

bootstrap = Bootstrap(app)

技術分享圖片

技術分享圖片

技術分享圖片

07-自定義錯誤頁面

最常見的錯誤代碼有兩個:404,500。使用 app.errorhandler 裝飾器為這兩個錯誤提供自定義的處理函數。

@app.errorhandler(404)
def page_not_found(e):
    return render_template(404.html), 404

@app.errorhandler(500)
def page_not_found(e):
    return render_template(500.html), 500

模板的編寫-404、500

template/base.html的內容,繼承了bootstrap/base.html的新模板。通過繼承 template/base.html 模板編寫自定義的404錯誤頁面就簡單了。

# template/404.html
{% extends ‘‘base.html %}

{% block title %}Flasky - Page Not Found{% endblock %}

{% block page_content %}
    <div class="page-header">
        <h1>Not Found</h1>
    </div>
{% endblock %}

08-靜態文件

默認設置下,Flask在應用根目錄中名為static的子目錄中,尋找靜態文件。

url_for(static, filename=favicon.ico)

09-使用Flask-Moment 本地化日期和時間

# 安裝

pip install flask-moment

初始化

from flask_moment import Moment

moment = Moment(app)

templates/base.html 引用 Moment.js庫

{% block script %}
{{ super }}
{{ moment.include_moment() }}
{% endblock %}

templates/index.html:使用Flask-Moment渲染時間戳

<p>The local date and time is {{ moment(current_time).format(‘LLL‘) }}.</p>

<p>That was {{ moment(current_time).fromNow(refresh=True) }}</p>

fromNow()渲染相對時間戳,會自動刷新時間,最開始顯示為 "a few seconds ago",但設定refresh=True其內容會隨著時間的推移而更新。

10-Web表單 Flask-WTF

# 安裝

pip install flask-wtf

配置Flask-WTF

app = Flask(__name__)

app.config[SECRET_KEY] = hard to guess string

Falsk-WTF配置一個密鑰,是為了防止表單遭到跨站請求偽造(CSRF)攻擊。

11-簡單驗證

from flask import Flask,request,render_template
from wtforms import Form,StringField
from wtforms.validators import Length,EqualTo

app = Flask(__name__)

class RegistForm(Form):
    username = StringField(validators=[Length(min=3,max=10,message=用戶名必須在3到10位之間)])
    password = StringField(validators=[Length(min=6,max=10,message=密碼必須6到10位之間)])
    password_repeat = StringField(validators=[Length(min=6,max=10),
                                              EqualTo("password",message=密碼不一致)])

@app.route(/)
def hello_world():
    return Hello World!

@app.route(/regist/,methods=[GET,POST])
def regist():
    if request.method == GET:
        return render_template(regist.html)
    else:
        form = RegistForm(request.form)
        if form.validate():
            return success
        else:
            print(form.errors)
            return fail

if __name__ == __main__:
    app.run()

技術分享圖片

技術分享圖片

from wtforms import Form,StringField,IntegerField
from wtforms.validators import Length,EqualTo,Email,InputRequired,NumberRange
from wtforms.validators import Regexp,URL,ValidationError


class LoginForm(Form):
    email = StringField(validators=[Email(message=郵箱格式不正確)])
    username = StringField(validators=[InputRequired(message=這個字段必須要填)])
    age = IntegerField(validators=[NumberRange(min=18,max=100)])
    phone = StringField(validators=[Regexp(r1[38745]\d{9})])
    homepage = StringField(validators=[URL()])
    captcha = StringField(validators=[Length(4,4)])

    # 自定義驗證器
    def validate_captcha(self,field):
        if field.data != 1234:      #field.data:用戶提交過來的數據
            raise ValidationError(驗證碼錯誤)          #如果驗證失敗,就拋出驗證失敗的異常

12-使用wtfforms渲染模板

forms.py

class SettingsForm(Form):
    username = StringField(label="用戶名:",validators=[InputRequired(message=這個字段必須要填)])
    age = IntegerField(年齡:,validators=[NumberRange(min=18, max=100)])
    remeber = BooleanField(記住我)
    tags = SelectField(標簽,choices=[(1,python),(2,django)])

views.py

@app.route(/settings/,methods=[GET,POST])
def settings():
    if request.method == GET:
        form = SettingsForm()
        return render_template(settings.html,form=form)
    else:
        pass

template.html

<form action="" method="post">
{#    括號裏面可以添加樣式#}
    <p>{{ form.username.label }} {{ form.username(class="") }}</p>
    <p>{{ form.age.label }} {{ form.age() }}</p>
    <p>{{ form.remeber.label }} {{ form.remeber() }}</p>
    <p>{{ form.tags.label }} {{ form.tags() }}</p>
    <p><input type="submit" value="提交"></p>
</form>

技術分享圖片

13-在視圖函數中處理表單

在視圖函數index()有兩個任務:一是渲染表單,二是接收用戶在表單中填寫的數據。

@app.route(/, methods=[GET, POST])
def index():
    name = None
    form = NameForm()
    if form.validate_on_submit():
        name = form.name.data
        form.name.data = ‘‘
    return render_template(index.html, form=form, name=name)

如果沒有指定methods參數,則視圖函數只為GET請求處理程序。

14-閃現消息

from flask import Flask, flash, render_template, redirect, url_for, session

@app.route(/, methods=[GET, POST])
def index():
    form = NameForm()
    if form.validate_on_submit():
        old_name = session.get(name)
        if old_name is not None and old_name != form.name.data:
            flash(Looks like you have changed your name!)
        session[name] = form.name.data
        return redirect(url_for(index))
    return redirect(index.html, form=form, name=session.get(name))

調用flash()函數,在發給客戶端的下一個響應中顯示一個消息。get_flashed_messages()函數來開放給模板,用於獲取並渲染閃現消息。

技術分享圖片

flask(二)之Jinja2模板與Flask-WTF