Flask--wtforms快速使用和表單驗證(附示例)

1、Form類

  表單提供WTForms中最高級別的API。它們包含您的字段定義,委託驗證,獲取輸入,聚合錯誤,而且一般用做將全部內容組合在一塊兒的粘合劑。html

class wtforms.form.Form 聲明式表格基類。html5

__init__(formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs)
formdata:用於傳遞來自Enduser的數據,一般爲request.POST或等效數據
    obj:若是formdata爲空或不提供,則檢查該對象以匹配字段名稱的屬性,這些字段將用於字段值。
    prefix:若是提供,全部字段的名稱都將以值做爲前綴。
    data:接受數據字典。只有在不存在格式化數據和obj的狀況下,纔會使用此方法。
    meta:若是提供,這是一個值字典,用於覆蓋此窗體的元實例上的屬性。
    初始化表單。這一般是在應用程序中的視圖/控制器上下文中完成的。構造表單時,字段根據表單數據、obj和kwargs填充它們的輸入。

屬性:

data
    包含每一個字段的數據的字典
errors
包含每一個字段的錯誤列表的DECT。若是沒有驗證表單,或者沒有錯誤,則爲空。

meta
這是一個包含各類配置選項以及自定義表單行爲的能力的對象。有關可使用類元選項自定義的內容的更多信息,請參見類元文檔。

方法:

   validate():經過在每一個字段上調用Value來驗證表單,將任何額外的Form.Value_<field name>驗證器傳遞給字段驗證器。
    populate_obj(obj):使用表單字段中的數據填充傳遞的obj的屬性。
    __iter__():按建立順序迭表明單字段。
    __contains__(name):若是指定的字段是此表單的成員,則返回True。

2、Fields

字段

字段負責渲染和數據轉換,他們委託validators進行數據驗證。python

字段定義

字段以聲明方式定義爲表單上的成員:正則表達式

class MyForm(Form):
    name    = StringField(u'Full Name', [validators.required(), validators.length(max=10)])
    address = TextAreaField(u'Mailing Address', [validators.optional(), validators.length(max=200)])

在表單上定義字段時,將保存構造參數,直到實例化表單。在表單實例化時,使用定義中指定的全部參數建立字段的副本。該字段的每一個實例都保留其本身的字段數據和錯誤列表。flask

標籤和驗證器能夠做爲順序參數傳遞給構造函數,而全部其餘參數應做爲關鍵字參數傳遞。某些字段(例如SelectField)也能夠採用其餘特定於字段的關鍵字參數。有關這些信息,請參閱內置字段參考。less

字段的基類(wtforms.fields.Field)

存儲和處理數據,併爲表單字段生成HTML。ide

字段實例包含該實例的數據以及在表單中呈現它的功能。它們還包含許多屬性,能夠在模板中使用這些屬性來呈現字段和標籤。函數

__init__(label = None,validators = None,filters =(),description ='',id = None,default = None,widget = None,render_kw = None,_form = None,_name = None,_prefix ='',_ translations =無,_meta =無)
label - 字段的標籤。
驗證器 -驗證的序列時要調用驗證被調用。
filters - 按進程在輸入數據上運行的一系列過濾器。
description - 字段的描述,一般用於幫助文本。
id - 用於字段的id。表單設置了合理的默認值,您不須要手動設置。
default - 若是未提供表單或對象輸入,則分配給字段的默認值。多是可贖回的。
widget - 若是提供,則覆蓋用於呈現字段的窗口小部件。
render_kw(dict) - 若是提供,則提供一個字典,該字典提供將在呈現時提供給窗口小部件的默認關鍵字。
_form - 包含此字段的表單。在施工期間,它由表格自己傳遞。你永遠不該該本身傳遞這個值。
_name - 此字段的名稱,由封閉表單在構造期間傳遞。你永遠不該該本身傳遞這個值。
_prefix - 前綴爲此字段的表單名稱的前綴,在構造期間由封閉表單傳遞。
_translations - 提供消息翻譯的翻譯對象。一般在施工期間經過封閉的形式經過。有關消息轉換的信息,請參閱 I18n文檔。
_meta - 若是提供,這是表單中的'meta'實例。你一般不會本身經過。

屬性

name
此字段的HTML表單名稱。這是您的表單中定義的名稱,前綴爲傳遞給Form構造函數的前綴。

short_name
此字段的未加前綴的名稱。

id
此字段的HTML ID。若是未指定,則生成此選項以使其與字段名稱相同。

label
這是一個Label在做爲字符串計算時返回HTML 構造的實例。<label for="id">

default
這是您做爲字段構造函數的默認值傳遞的任何內容,不然爲None。

description
一個字符串,包含在構造函數中傳遞給字段的描述值; 這不是HTML轉義。

errors
包含此字段的驗證錯誤的序列。

process_errors
輸入處理期間得到的錯誤。這些將在驗證時添加到錯誤列表中。

widget
用於渲染字段的小部件。
type 此字段的類型,做爲字符串。

驗證

validate(form,extra_validators =())
驗證字段並返回True或False。self.errors將包含驗證期間引起的任何錯誤。這一般只由Form.validate調用。
子字段不該覆蓋此字段,而是覆蓋 pre_validate,post_validate或二者,具體取決於需求。

errors
若是validate遇到任何錯誤,它們將被插入此列表中。

3、基本字段

class wtforms.fields.BooleanField
class wtforms.fields.DateField
class wtforms.fields.DateTimeField
class wtforms.fields.DecimalField
class wtforms.fields.FileField
class wtforms.fields.MultipleFileField
class wtforms.fields.FloatField
class wtforms.fields.IntegerField
class wtforms.fields.RadioField
class wtforms.fields.SelectField
class wtforms.fields.SelectMultipleField
class wtforms.fields.StringField

4、Validators

驗證器只需輸入一個輸入,驗證它是否知足某些標準,例如字符串的最大長度並返回。或者,若是驗證失敗,則引起a ValidationError該系統很是簡單靈活,容許您在字段上連接任意數量的驗證器。post

內置驗證器ui

class wtforms.validators.DataRequired(message=None):

此驗證器檢查data字段上的屬性是否爲「true」值(實際上,它確實如此。)此外,若是數據是字符串類型,則僅包含空格字符的字符串將被視爲false。

class wtforms.validators.EqualTo(fieldnamemessage=None)

validators.EqualTo('pwd', message="兩次密碼不一致")
比較兩個字段的值。

class wtforms.validators.Email(message=None)

驗證電子郵件地址。

class wtforms.validators.InputRequired(message=None)

驗證是否爲此字段提供了輸入。

 class wtforms.validators.Regexpregexflags = 0message = None 

根據用戶提供的regexp驗證字段。
regex - 要使用的正則表達式字符串。也能夠是編譯正則表達式模式。
flags - 要使用的regexp標誌,例如re.IGNORECASE。若是正則表達式不是字符串,則忽略 。
message - 出現驗證錯誤時引起的錯誤消息。

自定義驗證器

class MyForm(Form):
    name = StringField('Name', [InputRequired()])

    def validate_name(form, field):
        if len(field.data) > 50:
            raise ValidationError('Name must be less than 50 characters')
def my_length_check(form, field):
    if len(field.data) > 50:
        raise ValidationError('Field must be less than 50 characters')

class MyForm(Form):
    name = StringField('Name', [InputRequired(), my_length_check])

5、widgets

窗口小部件是用於將字段呈現爲其可用表示的類,一般是XHTML。調用字段時,默認行爲是將呈現委託給其窗口小部件。提供此抽象以即可以輕鬆建立窗口小部件以自定義現有字段的呈現。

 

內置小部件

class wtforms.widgets.ListWidget(html_tag='ul'prefix_label=True)

將字段列表呈現爲ul或ol列表。

class wtforms.widgets.Input(input_type=None)

渲染基本<input>字段。

class wtforms.widgets.TextInput

渲染單行文本輸入。

class wtforms.widgets.PasswordInput(hide_value=True)

呈現密碼輸入。

class wtforms.widgets.CheckboxInput

渲染一個複選框。

class wtforms.widgets.FileInput

渲染文件選擇器輸入。

class wtforms.widgets.TextArea

呈現多行文本區域。

class wtforms.widgets.Select(multiple=False)

呈現選擇字段。
若是multiple爲True,則應在渲染時指定size屬性以使該字段有用。

6、用戶註冊

from flask import Blueprint,render_template,request
from wtforms.fields import simple
from wtforms.fields import html5
from flask_wtf import FlaskForm
from wtforms.fields import core
from wtforms import StringField
from wtforms import widgets,validators

class MyForm(FlaskForm):
# == == == == == == == == == == == =simple == == == == == == == == == == == == == =
    name = StringField(
        label='姓名:',
        validators=[validators.DataRequired()],
        widget=widgets.TextInput(),
        render_kw={"class": "form-control"},  # 添加一些樣式,用於Bootstrap
    )

    pwd = simple.PasswordField(
        label="密碼",
        validators=[
            validators.DataRequired(message="密碼不能爲空")
        ]
    )

    pwd_confim = simple.PasswordField(
        label="重複密碼",
        validators=[
            validators.DataRequired(message='重複密碼不能爲空.'),
            validators.EqualTo('pwd', message="兩次密碼不一致")
        ],
        widget=widgets.PasswordInput(),
        render_kw={'class': 'form-control'}
    )
#========================html5============================
    email = html5.EmailField(  # 注意這裏用的是html5.EmailField
        label='郵箱',
        validators=[
            validators.DataRequired(message='郵箱不能爲空.'),
            validators.Email(message='郵箱格式錯誤')
        ],
        widget=widgets.TextInput(input_type='email'),
        render_kw={'class': 'form-control'}
    )

#===================如下是用core來調用的=======================
    gender = core.RadioField(
            label="性別",
            choices=(
                (1,""),
                (1,""),
            ),
            coerce=int  #限制是int類型的
        )
    city = core.SelectField(
            label="城市",
            choices=(
                ("bj","北京"),
                ("sh","上海"),
            )
        )
    hobby = core.SelectMultipleField(
        label='愛好',
        choices=(
            (1, '籃球'),
            (2, '足球'),
        ),
        coerce=int
    )
    favor = core.SelectMultipleField(
        label="喜愛",
        choices=(
            (1, '籃球'),
            (2, '足球'),
        ),
        widget = widgets.ListWidget(prefix_label=False),
        option_widget = widgets.CheckboxInput(),
        coerce = int,
        default = [1, 2]
    )


    def __init__(self, *args, **kwargs):  # 這裏的self是一個RegisterForm對象
        '''重寫__init__方法'''
        super(MyForm, self).__init__(*args, **kwargs)  # 繼承父類的init方法
        self.favor.choices = ((1, '籃球'), (2, '足球'), (3, '羽毛球'))  # 吧RegisterForm這個類裏面的favor從新賦值
        # 方法驗證
        def validate_pwd_confim(self, field, ):
            '''
            自定義pwd_config字段規則,例:與pwd字段是否一致
            :param field:
            :return:
            '''
            # 最開始初始化時,self.data中已經有全部的值
            if field.data != self.data['pwd']:
                # raise validators.ValidationError("密碼不一致") # 繼續後續驗證
                raise validators.StopValidation("密碼不一致")  # 再也不繼續後續驗證


register = Blueprint("register",__name__)

@register.route("/regist",methods=["GET","POST"])
def regist():
    if request.method == "GET":
        form = MyForm()
        return render_template("regis.html",forms = form)


    form = MyForm(formdata=request.form)
    if form.validate(): #驗證是否成功
        print("數據校驗經過")
    else:
        return render_template("regis.html",forms = form)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>註冊</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>


<form action="" method="post">
{#    {{ form.name.label }}#}
{#    {{ form.name }}#}
{#    {{ form.name.errors.0 }}#}
    {% for form in forms %}
        <p>
            {% if form.label.text == "CSRF Token" %}

            {% else %}
                {{ form.label }}
                {{ form }}
                <span style="color: red;">{{ form.errors.0 }}</span>

            {% endif %}


        </p>
    {% endfor %}

    <input type="submit" value="提交">

</form>

</body>
</html>

相關文章
相關標籤/搜索