wtforms 使用




wtforms是一個表單模板庫, 下面以修改密碼表單為例簡單說明其用法.
我們可以用python代碼定義form的基本元素, 比如用戶名/郵箱, 並給定各個元素的validation條件.

然后在render_template()方法中, 將python的form類傳遞給html模板. 在模板上, 需要有placeholder來接納python傳過來的form元素.


使用wtforms的好處是:
1. form驗證可以使用python來做, 不必將驗證代碼放到javascript中.
2. 在python視圖函數中, 可以很方便地獲取表單元素, 比如使用form.username.data, 即可獲取表單上的username值.
3. 可以簡化html模板的設計. 采用Flask-Bootstrap 擴展或者使用一些jinja2 marco都能簡化html代碼.
4. 更重要的好處是, 將validation邏輯從表現層中解耦

 
下面僅講解wtforms和bootstrap的結合使用, 而不涉及wtforms的基本用法.

bear-z寫的bootstrap的macro
http://bear-z.com/python/render-bootstrap-3-forms-with-wtforms-and-jinja/


wtforms和bootstrap結合使用的詳解
http://pythonthusiast.pythonblogs.com/230_pythonthusiast/archive/1315_flask_biography_tutorial_part_vi__adding_sign_up_form_using_bootstrap_3_and_flask-wtf.html


Flask-Bootstrap的簡單用法
1. 安裝Flask-Bootstrap后, 將Flask-Bootstrap的bootstrap模板目錄放在我們自己的templates目錄下, 即形成一個二級子目錄.
2. 將flask的app做封裝
    from flask_bootstrap import Bootstrap
    Bootstrap(app)
3. 定義python的一個WTF form類, 比如 MyForm
4. 在flask的view函數中, 將MyForm實例傳到模板html中,  即render_template('MyForm.html',form=MyForm())
5. 在MyForm.html模板中, 引入flask_bootstrap的wtf macro文件, 最簡單的方法是wtf.quick_form(), 即可將 MyForm python類定義的所有元素渲染到html上.  
  {% import "bootstrap/wtf.html" as wtf %}
  ....
    <div>         
        {{ wtf.quick_form(form, id="myform", form_type="horizontal", horizontal_columns=('sm', 2, 5)) }}
        <!-- 上面horizontal_columns()后兩個參數是用來標示每一行的label和textbox的寬度 -->
    </div>


Flask-Bootstrap的quick_form()生成的html往往只適用於簡單的排版, 所以比較適合做demo. 即使直接用wtf.form_field()來渲染每個元素, 也沒有辦法指定css class, 靈活度不高. 不過, 我們可提取出Flask-Bootstrap生成的html樣式, 做為下一步美化的基礎.


bear-z寫的bootstrap的macro, 和Flask-Bootstrap相比, 靈活度高一些, 可以通過class_參數為每個元素指定css class.
{% import "bootstrap/bearz_wtf.html" as wtf2 %}
{{ wtf2.render_field(form.email, label_visible=false, placeholder='userID', type='email',class_='col-md-8') }}


涉及到表單提交, flask視圖函數其實都是一個樣子. 先看請求類型, 如是POST, 驗證form上的數據, 驗證通過則更新, 不通過則返回到原來的Form. 如請求是GET, 則表明是新的請求, 初始化一個新的Form, 並做html渲染.

下面是一個更新密碼的示例.

##############################################
#flask view 模塊
##############################################
@mod.route('/MyApp/updatePwd/', methods=['GET','POST'])
def udpatePwd():
    if request.method == 'POST':  # construct WTF form object based on request data
        form = UserPwdForm(request.form)
        if form.validate():       # WTForm validation OK
            user=User.getUser(form.EMPNO.data)
            aborted=False
            if user is None:
                aborted=True
                form.EMPNO.errors.append('This EmpNo does not exist.')
            if not aborted and not User.checkUserPwd(form.EMPNO.data, form.PWD.data):
                aborted=True    
                form.PWD.errors.append('Old password is not correct.')
            if aborted:
                return _navigateToUpdatePwd(form)  # return the page with error message
            else:  # all validation OK
                try:
                    User.updatePassword(form.EMPNO.data,form.NewPWD.data)
                    return _navigateSuccessfulPage()
                except Exception as e:
                    return _navigateErrorPage(logger=current_app.logger, exception=e)
        else:  # validation failed
            return _navigateToUpdatePwd(form)         
        
    else:  # GET request
        return _navigateToUpdatePwd(UserPwdForm())
 
 
def _navigateToUpdatePwd(form):
    return render_template("form_update_pwd.html",  
                            form=form,
                            )     


def _navigateSuccessfulPage():
    return render_template("form_successful.html",  
                            )      
                   
                   
def _navigateErrorPage(logger, friendlyErrorMsg=None, exception=None):
    if exception:
        msg='%s'%exception
        tracebackInfo=traceback.format_exc()
        tracebackInfo=tracebackInfo.replace(chr(10), '<br>')
        tracebackInfo=tracebackInfo.replace(chr(13), '<br>')

    if friendlyErrorMsg:
        msg=friendlyErrorMsg
        
    logger.error(msg)    
    if exception:
        logger.exception(exception)  
   
    #output the msg highlighted in danger  
    flash(msg, 'error')
    return render_template("form_error.html",  
                            tracebackInfo=tracebackInfo
                            )     
                       
                       
                   

##############################################                            
#flask form 模塊
##############################################
from flask_wtf import Form
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, EqualTo, Length, InputRequired
from wtforms.fields.simple import PasswordField

class UserPwdForm(Form):
    
    EMPNO=StringField('Emp No',validators=[
        DataRequired('Please enter Emp No'),
        Length(min = 1, max = 20,message='length must between 1 and 20')
    ])
    
    PWD=PasswordField('Old password',validators=[
        DataRequired('Please enter old password'),
    ])    
        
    NewPWD=PasswordField('New password',validators=[
        DataRequired('Please enter new password'),
    ])    
    
    RptNewPWD=PasswordField('Confirm new password',validators=[
        DataRequired('Please confirm new password again'),
        EqualTo('NewPWD','Password must be match')
    ])        
        
    submit = SubmitField('Submit')    


    
    
##############################################    
# html文件 form_update_pwd.html    
##############################################
{% if not is_xhr|default(false) %}{% extends "report_base.html" %}{% endif %}
{% import "bootstrap/wtf.html" as wtf %}
{% import "bootstrap/bearz_wtf.html" as wtf2 %}                    


{% block other_head_javascript %}
    <script src="/static/js/jquery.min.js"></script>
{% endblock %}

 
{% block content %}
 
      <h1>Update password</h1>
     
       <div>         
           {{ wtf.quick_form(form, id="FormUpdatePwd", form_type="horizontal", horizontal_columns=('sm', 2, 5)) }}
       </div>
 
        
{% endblock %}



##############################################
# html文件 form_successful.html
##############################################
{% if not is_xhr|default(false) %}{% extends "report_base.html" %}{% endif %}
{% import "bootstrap/wtf.html" as wtf %}
{% import "bootstrap/bearz_wtf.html" as wtf2 %}
                     

{% block other_head_javascript %}
    <script src="/static/js/jquery.min.js"></script>
{% endblock %}

 
{% block content %}
 
<h1>Updated successfully.</h1>
        
{% endblock %}

 


理解session和cookie
http://lucindabfls.blog.163.com/blog/static/1247404702010326103548751/
http://hqhou.blog.163.com/blog/static/852039352013431033327/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM