1. 程式人生 > >Flask學習【第7篇】:Flask中的wtforms使用 flask中的wtforms使用

Flask學習【第7篇】:Flask中的wtforms使用 flask中的wtforms使用

flask中的wtforms使用

一、簡單介紹flask中的wtforms

WTForms是一個支援多個web框架的form元件,主要用於對使用者請求資料進行驗證。

安裝:

pip3 install wtforms

二、簡單使用wtforms元件

1、使用者登入

具體程式碼:

複製程式碼
from  flask import Flask,render_template,request,redirect
from  wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import Form
from wtforms import validators from wtforms import widgets app = Flask(__name__,template_folder="templates") class Myvalidators(object): '''自定義驗證規則''' def __init__(self,message): self.message = message def __call__(self, form, field): print(field.data,"使用者輸入的資訊") if field.data == "haiyan": return None raise validators.ValidationError(self.message) class LoginForm(Form): '''Form''' name = simple.StringField( label="使用者名稱", widget=widgets.TextInput(), validators=[ Myvalidators(message="使用者名稱必須是haiyan"),#也可以自定義正則 validators.DataRequired(message="使用者名稱不能為空"), validators.Length(max=8,min=3,message="使用者名稱長度必須大於%(max)d且小於%(min)d") ], render_kw={"class":"form-control"} #設定屬性  ) pwd = simple.PasswordField( label="密碼", validators=[ validators.DataRequired(message="密碼不能為空"), validators.Length(max=8,min=3,message="密碼長度必須大於%(max)d且小於%(min)d"), validators.Regexp(regex="\d+",message="密碼必須是數字"), ], widget=widgets.PasswordInput(), render_kw={"class":"form-control"} ) @app.route('/login',methods=["GET","POST"]) def login(): if request.method =="GET": form = LoginForm() return render_template("login.html",form=form) else: form = LoginForm(formdata=request.form) if form.validate(): print("使用者提交的資料用過格式驗證,值為:%s"%form.data) return "登入成功" else: print(form.errors,"錯誤資訊") return render_template("login.html",form=form) if __name__ == '__main__': # app.__call__() app.run(debug=True)
複製程式碼

login.html

複製程式碼
<body>
<form action="" method="post" novalidate>
    <p>{{ form.name.label }} {{ form.name }} {{ form.name.errors.0 }}</p>
    <p>{{ form.pwd.label }} {{ form.pwd }} {{ form.pwd.errors.0 }}</p>
    <input type="submit" value="提交">
    <!--使用者名稱:<input type="text">-->
    <!--密碼:<input type="password">-->
    <!--<input type="submit" value="提交">-->
</form>
</body>
複製程式碼

2、使用者註冊

複製程式碼
from flask import Flask,render_template,redirect,request
from wtforms import Form
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators from wtforms import widgets app = Flask(__name__,template_folder="templates") app.debug = True 
=======================simple=========================== class RegisterForm(Form): name = simple.StringField( label="使用者名稱", validators=[ validators.DataRequired() ], widget=widgets.TextInput(), render_kw={"class":"form-control"}, default="haiyan" ) 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(RegisterForm,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("密碼不一致") # 不再繼續後續驗證 @app.route('/register',methods=["GET","POST"]) def register(): if request.method=="GET": form = RegisterForm(data={'gender': 1}) #預設是1, return render_template("register.html",form=form) else: form = RegisterForm(formdata=request.form) if form.validate(): #判斷是否驗證成功 print('使用者提交資料通過格式驗證,提交的值為:', form.data) #所有的正確資訊 else: print(form.errors) #所有的錯誤資訊 return render_template('register.html', form=form) if __name__ == '__main__': app.run()
複製程式碼

register.html

複製程式碼
<body>
<h1>使用者註冊</h1>
<form method="post" novalidate style="padding:0  50px">
    {% for item in form %}
    <p>{{item.label}}: {{item}} {{item.errors[0] }}</p>
    {% endfor %}
    <input type="submit" value="提交">
</form>
</body>
複製程式碼

 3、meta

複製程式碼
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, render_template, request, redirect, session
from wtforms import Form
from wtforms.csrf.core import CSRF
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple from wtforms import validators from wtforms import widgets from hashlib import md5 app = Flask(__name__, template_folder='templates') app.debug = True class MyCSRF(CSRF): """ Generate a CSRF token based on the user's IP. I am probably not very secure, so don't use me. """ def setup_form(self, form): self.csrf_context = form.meta.csrf_context() self.csrf_secret = form.meta.csrf_secret return super(MyCSRF, self).setup_form(form) def generate_csrf_token(self, csrf_token): gid = self.csrf_secret + self.csrf_context token = md5(gid.encode('utf-8')).hexdigest() return token def validate_csrf_token(self, form, field): print(field.data, field.current_token) if field.data != field.current_token: raise ValueError('Invalid CSRF') class TestForm(Form): name = html5.EmailField(label='使用者名稱') pwd = simple.StringField(label='密碼') class Meta: # -- CSRF # 是否自動生成CSRF標籤 csrf = True # 生成CSRF標籤name csrf_field_name = 'csrf_token' # 自動生成標籤的值,加密用的csrf_secret csrf_secret = 'xxxxxx' # 自動生成標籤的值,加密用的csrf_context csrf_context = lambda x: request.url # 生成和比較csrf標籤 csrf_class = MyCSRF # -- i18n # 是否支援本地化 # locales = False locales = ('zh', 'en') # 是否對本地化進行快取 cache_translations = True # 儲存本地化快取資訊的欄位 translations_cache = {} @app.route('/index/', methods=['GET', 'POST']) def index(): if request.method == 'GET': form = TestForm() else: form = TestForm(formdata=request.form) if form.validate(): print(form) return render_template('index.html', form=form) if __name__ == '__main__': app.run()
複製程式碼

 

一、簡單介紹flask中的wtforms

WTForms是一個支援多個web框架的form元件,主要用於對使用者請求資料進行驗證。

安裝:

pip3 install wtforms

二、簡單使用wtforms元件

1、使用者登入

具體程式碼:

複製程式碼
from  flask import Flask,render_template,request,redirect
from  wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import Form
from wtforms import validators from wtforms import widgets app = Flask(__name__,template_folder="templates") class Myvalidators(object): '''自定義驗證規則''' def __init__(self,message): self.message = message def __call__(self, form, field): print(field.data,"使用者輸入的資訊") if field.data == "haiyan": return None raise validators.ValidationError(self.message) class LoginForm(Form): '''Form''' name = simple.StringField( label="使用者名稱", widget=widgets.TextInput(), validators=[ Myvalidators(message="使用者名稱必須是haiyan"),#也可以自定義正則 validators.DataRequired(message="使用者名稱不能為空"), validators.Length(max=8,min=3,message="使用者名稱長度必須大於%(max)d且小於%(min)d") ], render_kw={"class":"form-control"} #設定屬性  ) pwd = simple.PasswordField( label="密碼", validators=[ validators.DataRequired(message="密碼不能為空"), validators.Length(max=8,min=3,message="密碼長度必須大於%(max)d且小於%(min)d"), validators.Regexp(regex="\d+",message="密碼必須是數字"), ], widget=widgets.PasswordInput(), render_kw={"class":"form-control"} ) @app.route('/login',methods=["GET","POST"]) def login(): if request.method =="GET": form = LoginForm() return render_template("login.html",form=form) else: form = LoginForm(formdata=request.form) if form.validate(): print("使用者提交的資料用過格式驗證,值為:%s"%form.data) return "登入成功" else: print(form.errors,"錯誤資訊") return render_template("login.html",form=form) if __name__ == '__main__': # app.__call__() app.run(debug=True)
複製程式碼

login.html

複製程式碼
<body>
<form action="" method="post" novalidate>
    <p>{{ form.name.label }} {{ form.name }} {{ form.name.errors.0 }}</p>
    <p>{{ form.pwd.label }} {{ form.pwd }} {{ form.pwd.errors.0 }}</p>
    <input type="submit" value="提交">
    <!--使用者名稱:<input type="text">-->
    <!--密碼:<input type="password">-->
    <!--<input type="submit" value="提交">-->
</form>
</body>
複製程式碼

2、使用者註冊

複製程式碼
from flask import Flask,render_template,redirect,request
from wtforms import Form
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators from wtforms import widgets app = Flask(__name__,template_folder="templates") app.debug = True 
=======================simple=========================== class RegisterForm(Form): name = simple.StringField( label="使用者名稱", validators=[ validators.DataRequired() ], widget=widgets.TextInput(), render_kw={"class":"form-control"}, default="haiyan" ) 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(RegisterForm,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("密碼不一致") # 不再繼續後續驗證 @app.route('/register',methods=["GET","POST"]) def register(): if request.method=="GET": form = RegisterForm(data={'gender': 1}) #預設是1, return render_template("register.html",form=form) else: form = RegisterForm(formdata=request.form) if form.validate(): #判斷是否驗證成功 print('使用者提交資料通過格式驗證,提交的值為:', form.data) #所有的正確資訊 else: print(form.errors) #所有的錯誤資訊 return render_template('register.html', form=form) if __name__ == '__main__': app.run()
複製程式碼

register.html

複製程式碼
<body>
<h1>使用者註冊</h1>
<form method="post" novalidate style="padding:0  50px">
    {% for item in form %}
    <p>{{item.label}}: {{item}} {{item.errors[0] }}</p>
    {% endfor %}
    <input type="submit" value="提交">
</form>
</body>
複製程式碼

 3、meta

複製程式碼
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, render_template, request, redirect, session
from wtforms import Form
from wtforms.csrf.core import CSRF
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple from wtforms import validators from wtforms import widgets from hashlib import md5 app = Flask(__name__, template_folder='templates') app.debug = True class MyCSRF(CSRF): """ Generate a CSRF token based on the user's IP. I am probably not very secure, so don't use me. """ def setup_form(self, form): self.csrf_context = form.meta.csrf_context() self.csrf_secret = form.meta.csrf_secret return super(MyCSRF, self).setup_form(form) def generate_csrf_token(self, csrf_token): gid = self.csrf_secret + self.csrf_context token = md5(gid.encode('utf-8')).hexdigest() return token def validate_csrf_token(self, form, field): print(field.data, field.current_token) if field.data != field.current_token: raise ValueError('Invalid CSRF') class TestForm(Form): name = html5.EmailField(label='使用者名稱') pwd = simple.StringField(label='密碼') class Meta: # -- CSRF # 是否自動生成CSRF標籤 csrf = True # 生成CSRF標籤name csrf_field_name = 'csrf_token' # 自動生成標籤的值,加密用的csrf_secret csrf_secret = 'xxxxxx' # 自動生成標籤的值,加密用的csrf_context csrf_context = lambda x: request.url # 生成和比較csrf標籤 csrf_class = MyCSRF # -- i18n # 是否支援本地化 # locales = False locales = ('zh', 'en') # 是否對本地化進行快取 cache_translations = True # 儲存本地化快取資訊的欄位 translations_cache = {} @app.route('/index/', methods=['GET', 'POST']) def index(): if request.method == 'GET': form = TestForm() else: form = TestForm(formdata=request.form) if form.validate(): print(form) return render_template('index.html', form=form) if __name__ == '__main__': app.run()
複製程式碼