Flask-1-08--表單

web表單是web應用程序的基本功能。

它是HTML頁面中負責數據採集的部件。表單有三個部分組成:表單標籤、表單域、表單按鈕。表單容許用戶輸入數據,負責HTML頁面數據採集,經過表單將用戶輸入的數據提交給服務器。

不管前端是否校驗了表單數據的安全性合法性,可是後端也是須要有一套單獨的校驗邏輯,由於若是有人不是經過你前端頁面給後端發數據,後端尚未校驗就是很麻煩的事情,在Flask中有處理表單的插件,很是簡便,就是Flask-wtf,它封裝了WTForms,而且它有驗證表單數據的功能

WTForms支持的HTML標準字段

字段對象

說明

StringField

文本字段

TextAreaField

多行文本字段

PasswordField

密碼文本字段

HiddenField

隱藏文本字段

DateField

文本字段,值爲datetime.date格式

DateTimeField

文本字段,值爲datetime.datetime格式

IntegerField

文本字段,值爲整數

DecimalField

文本字段,值爲decimal.Decimal

FloatField

文本字段,值爲浮點數

BooleanField

複選框,值爲True和False

RadioField

一組單選框

SelectField

下拉列表

SelectMultipleField

下拉列表,可選擇多個值

FileField

文本上傳字段

SubmitField

表單提交按鈕

FormField

把表單做爲字段嵌入另外一個表單

FieldList

一組指定類型的字段

 

WTForms經常使用驗證函數

驗證函數

說明

DataRequired

確保字段中有數據

EqualTo

比較兩個字段的值,經常使用於比較兩次密碼輸入

Length

驗證輸入的字符串長度

NumberRange

驗證輸入的值在數字範圍內

URL

驗證URL

AnyOf

驗證輸入值在可選列表中

NoneOf

驗證輸入值不在可選列表中

注意:使用Flask-WTF須要配置參數SECRET_KEY。CSRF_ENABLED是爲了CSRF(跨站請求僞造)保護。 SECRET_KEY用來生成加密令牌,當CSRF激活的時候,該設置會根據設置的密匙生成加密令牌。html

接下來經過一個簡單的案例,來使用這個WTF,建立一個wtf_demo.py的文件

使用流程:首先定義一個表單的類,繼承自FlaskForm在這個類,在類中建立字段,分別導入須要的字段的類[好比用戶名導入StringField,密碼導入PasswordField...根據本身的需求導入就好],準備就基本完成,接下來定義一個視圖,在視圖中建立表單對象,也就是你剛纔建立的類對象,完成後返回你指定的模板文件,和表單對象便可,這裏咱們建立的表單對象爲form

 1 # coding:utf-8
 2 from flask import Flask, render_template, redirect, url_for, session
 3 from flask_wtf import FlaskForm
 4 from wtforms import StringField, PasswordField, SubmitField
 5 from wtforms.validators import DataRequired, EqualTo
 6 
 7 import sys
 8 reload(sys)
 9 sys.setdefaultencoding('utf8')
10 
11 app = Flask(__name__)
12 app.config['SECRET_KEY'] = 'asd'
13 
14 
15 # 定義登錄表單
16 class RegisterForm(FlaskForm):
17     # 建立須要提交的字段
18     # validators 是驗證器 Datarequired 是不能爲空 EqualTo是和誰相等
19     username = StringField(label=u"用戶名", validators=[DataRequired(u'用戶名不能爲空')])
20     password = PasswordField(label=u'密碼', validators=[DataRequired(u'密碼不能爲空')])
21     password2 = PasswordField(label=u'確認密碼', validators=[DataRequired(u'確認密碼不能爲空'), EqualTo('password', u'兩次密碼不一致')])
22 
23     submit = SubmitField(label='提交')
24 
25 
26 @app.route('/register', methods=['post', 'get'])
27 def register():
28     # 建立表單對象, 若是是post請求,前端發送了數據,flask會把數據在構造form對象的時候,存放到對象中,因此不用驗證是get請求,仍是post請求
29     form = RegisterForm()
30 
31     # 判斷form中的數據是否合法
32     # 若是form中的數據徹底知足全部的驗證器,則返回真,不然返回假
33     if form.validate_on_submit():
34         # 表示前端發送的數據合法
35         # 獲取前端發送的數據
36         uname = form.username.data
37         pw = form.password.data
38         pw2 = form.password2.data
39         print(uname, pw, pw2)
40         # 添加到session中
41         session['username'] = uname
42         # 跳轉到index頁面
43         return redirect(url_for("index"))
44     return render_template('register.html', form=form)
45 
46 
47 @app.route('/index')
48 def index():
49     # 將登錄時候設置的session取出
50     username = session.get('username')
51     return "%s" % username
52 
53 
54 if __name__ == '__main__':
55     app.run(debug=True)
Python代碼
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <form method="post">
 9         {{ form.csrf_token }}
10 
11         {{ form.username.label }}
12         <p>{{ form.username }}</p>
13         <div>
14         {% for msg in form.username.errors %}
15             <p>{{ msg }}</p>
16         {% endfor %}
17         </div>
18         {{ form.password.label }}
19         <p>{{ form.password }}</p>
20         {% for msg in form.password.errors %}
21             <p>{{ msg }}</p>
22         {% endfor %}
23 
24         {{ form.password2.label }}
25         <p>{{ form.password2 }}</p>
26         {% for msg in form.password2.errors %}
27             <p>{{ msg }}</p>
28         {% endfor %}
29 
30         {{ form.submit }}
31     </form>
32 </body>
33 </html>
HTML代碼

注意:這裏必定要記得設置 SECRET_KEY, 後面的值本身定義或者使用Python生成均可以,也須要在HTML頁面中,設置csrf_token前端

展現結果

 

 

宏、繼承、包含:

相似於python中的函數,宏的做用就是在模板中重複利用代碼,避免代碼冗餘。

Jinja2支持宏,還能夠導入宏,須要在多處重複使用的模板代碼片斷能夠寫入單獨的文件,再包含在全部模板中,以免重複。

定義:

{#不帶參數宏的定義#}
{% macro input() %}
  <input type="text"
         name="username"
         value=""
         size="30"/>
{% endmacro %}
{#使用#}
{{ input() }}
{# 帶參數宏的定義 #}
{% macro input(name,value='',type='text',size=20) %}
    <input type="{{ type }}"
           name="{{ name }}"
           value="{{ value }}"
           size="{{ size }}"/>
{% endmacro %}

{#使用#}
{{ input(value='name',type='password',size=40)}}

簡單的經過一個示例展現一下到底如何使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
</head>
<body>
    {# 不帶參數   #}
    {% macro input() %}
        <input type="text" value="" size="30">
    {% endmacro %}

    <h1>input 1</h1>
    {{ input() }}
    <h1>input 2</h1>
    {{ input() }}
    {# 帶參數   #}
    {% macro input2(type, value, size) %}
        <input type="{{ type }}" value="{{ value }}" size="{{ size }}">
    {% endmacro %}
    <h1>input2 1</h1>
    {{ input2("password", "", 50) }}
    <h1>input2 2</h1>
    {{ input2("password", "", 10) }}
</body>
</html>
# coding:utf-8
from flask import Flask, render_template

app = Flask(__name__)


@app.route("/index")
def index():
    return render_template("index.html")


if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

這樣就能夠很是方便的複用咱們須要的代碼。還有一點要說明,就是帶默認參數也是能夠的

    {# 帶默認參數   #}
    {% macro input3(type="text", value="", size="30") %}
        <input type="{{ type }}" value="{{ value }}" size="{{ size }}">
    {% endmacro %}

    <h1>input3 1</h1>
    {{ input3() }}
    <h1>input3 2</h1>
    {{ input3(type='password') }}

固然在上面咱們也看到了jinja2的說明中,是支持宏,還有一句話就是也能夠導入宏,下面咱們來作一下展現

首先咱們須要定一個文件,來管理咱們要定義的宏,這裏建立一個macro_input.html

{% macro input4(type="text", value="", size="44") %}
    <input type="{{ type }}" value="{{ value }}" size="{{ size }}">
{% endmacro %}

在模板index.html 中使用python

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
</head>
<body>
    ...
    {# 導入宏 #}
    {% import "macro_input.html" as input_func %}
    <h1>input4 1</h1>
    {{ input_func.input4() }}

</body>
</html>

展現效果

 

 

 

 

模板繼承:

模板繼承是爲了重用模板中的公共內容。通常Web開發中,繼承主要使用在網站的頂部菜單、底部。這些內容能夠定義在父模板中,子模板直接繼承,而不須要重複書寫。

{% block top %}``{% endblock %}標籤訂義的內容,至關於在父模板中挖個坑,當子模板繼承父模板時,能夠進行填充。

子模板使用extends指令聲明這個模板繼承自哪?父模板中定義的塊在子模板中被從新定義,在子模板中調用父模板的內容可使用super()。

父模板:base.html

  {% block top %}
    頂部菜單
  {% endblock top %}

  {% block content %}
  {% endblock content %}

  {% block bottom %}
    底部
  {% endblock bottom %}

子模板:

  {% extends 'base.html' %}
  {% block content %}
   須要填充的內容
  {% endblock content %}
  • 模板繼承使用時注意點:

    • 不支持多繼承。

    • 爲了便於閱讀,在子模板中使用extends時,儘可能寫在模板的第一行。

    • 不能在一個模板文件中定義多個相同名字的block標籤。

    • 當在頁面中使用多個block標籤時,建議給結束標籤起個名字,當多個block嵌套時,閱讀性更好。

包含(Include)

Jinja2模板中,除了宏和繼承,還支持一種代碼重用的功能,叫包含(Include)。它的功能是將另外一個模板整個加載到當前模板中,並直接渲染。

示例:

include的使用

{\% include 'hello.html' %}

包含在使用時,若是包含的模板文件不存在時,程序會拋出TemplateNotFound異常,能夠加上ignore missing關鍵字。若是包含的模板文件不存在,會忽略這條include語句。

示例:

include的使用加上關鍵字ignore missing

{\% include 'hello.html' ignore missing %}
  • 宏、繼承、包含:

    • 宏(Macro)、繼承(Block)、包含(include)均能實現代碼的複用。

    • 繼承(Block)的本質是代碼替換,通常用來實現多個頁面中重複不變的區域。

    • 宏(Macro)的功能相似函數,能夠傳入參數,須要定義、調用。

    • 包含(include)是直接將目標模板文件整個渲染出來。

 Flask中的特殊變量和方法:在Flask中,有一些特殊的變量和方法是能夠在模板文件中直接訪問的。

config 對象:

{# config 對象就是Flask的config對象,也就是 app.config 對象。#}

{{ config.SQLALCHEMY_DATABASE_URI }}

request 對象:就是 Flask 中表示當前請求的 request 對象,request對象中保存了一次HTTP請求的一切信息。

request經常使用的屬性以下:

屬性 說明 類型
data 記錄請求的數據,並轉換爲字符串 *
form 記錄請求中的表單數據 MultiDict
args 記錄請求中的查詢參數 MultiDict
cookies 記錄請求中的cookie信息 Dict
headers 記錄請求中的報文頭 EnvironHeaders
method 記錄請求使用的HTTP方法 GET/POST
url 記錄請求的URL地址 string
files 記錄請求上傳的文件 *

使用

{{ request.url }}web

url_for 方法:url_for() 會返回傳入的路由函數對應的URL,所謂路由函數就是被 app.route() 路由裝飾器裝飾的函數。若是咱們定義的路由函數是帶有參數的,則能夠將這些參數做爲命名參數傳入。

{{ url_for('index') }}

{{ url_for('post', post_id=1024) }}

get_flashed_messages方法:返回以前在Flask中經過 flash() 傳入的信息列表。把字符串對象表示的消息加入到一個消息隊列中,而後經過調用 get_flashed_messages() 方法取出。

{% for message in get_flashed_messages() %}
    {{ message }}
{% endfor %}
相關文章
相關標籤/搜索