在使用Flask-WTF
的時候,使用qucik_form()
快速生成表單的確是很爽,可是生成的表單的樣式並非想要的,這個時候就不能使用qucik_form()
了。html
PS:目前還不是很熟悉Flask-WTF
的驗證表單的原理,好比Require()
驗證應該是用JS,EqualTo
這種就是放在後端處理的。有時間了須要好好讀一讀官方文檔。前端
在froms.py
中定義了以下的Register
表單:python
class RegisterForm(Form): """註冊表單""" username = StringField(u'暱稱', validators=[Required()]) email = StringField(u'郵箱', validators=[Required(), Email()]) password = PasswordField(u'密碼', validators=[Required(), Length(6, 12, message=u'密碼長度在6到12爲')]) password1 = PasswordField(u'確認密碼', validators=[Required(), Length(6, 12, message=u'密碼長度在6到12爲'), EqualTo('password', message=u'密碼必須一致')]) verification_code = StringField(u'驗證碼', validators=[Required(), Length(4, 4, message=u'填寫4位驗證碼')]) submit = SubmitField(u'註冊')
在verification_code
字段中,須要加載驗證碼圖片,此時在模板中使用qucik_form()
就很難處理了。後端
此時就須要手動控制表單的生成。session
在模板中,手動渲染很麻煩:post
<form action="" method="post" class="form" role="form"> {{ form.hidden_tag() }} <div class="form-group required"> {{ form.username.label(class="control-label") | safe }} {{ form.username(class="form-control", required=True) }} </div> <div class="form-group required"> {{ form.email.label(class="control-label") | safe }} {{ form.email(class="form-control", required=True) }} </div> {% if form.errors.password %} <div class="form-group has-error required"> {{ form.password.label(class="control-label") | safe }} {{ form.password(class="form-control", required=True) }} {% for error in form.errors.password %} <p class="help-block">{{ error }}</p> {% endfor %} </div> {% else %} <div class="form-group required"> {{ form.password.label(class="control-label") | safe }} {{ form.password(class="form-control", required=True) }} </div> {% endif %} {% if form.errors.password1 %} <div class="form-group has-error required"> {{ form.password1.label(class="control-label") | safe }} {{ form.password1(class="form-control", required=True) }} {% for error in form.errors.password1 %} <p class="help-block">{{ error }}</p> {% endfor %} </div> {% else %} <div class="form-group required"> {{ form.password1.label(class="control-label") | safe }} {{ form.password1(class="form-control", required=True) }} </div> {% endif %} {% if form.errors.verification_code %} <div class="form-group has-error required"> {{ form.verification_code.label(class="control-label") | safe }} {{ form.verification_code(class="form-control", required=True) }} {% for error in form.errors.verification_code %} <p class="help-block">{{ error }}</p> {% endfor %} </div> {% else %} <div class="form-group required"> {{ form.verification_code.label(class="control-label") | safe }} <label class="control-label"><img src="{{ url_for('static', filename='image/code/'+code_img) }}"></label> {{ form.verification_code(class="form-control", required=True) }} </div> {% endif %} {{ form.submit(class="btn btn-info submit") }} </form> <div class="register"> <a type="button" class="btn btn-info" style="width: 100%;" href="#">已有帳號?登陸</a> </div>
下面是在編寫以上代碼時遇到的坑:ui
在模板中須要處理form.errors
。若是表單驗證失敗,失敗的消息保存在form.errors
中。url
若是表單驗證錯誤,沒有處理`form.errors`的話前端就不會有任何提示,給人形成的錯覺就是`validate_on_submit`方法沒有執行。
不要忘記form.hidden_tag()
。這個是加載並隱藏csrf_token
。沒有csrf_token
,通常會報錯。spa
沒有銀彈
上面的代碼只實現了非空驗證、密碼是否相等驗證、密碼長度驗證等功能,不知道不用Flask-WTF
改用HTML
+ JS
實現是否是代碼量差很少。code
生成驗證碼使用PIL
來生成圖片。廖雪峯有介紹如何生成驗證碼圖片PIL-廖雪峯
views.py
中處理表單處理表單的邏輯:
每次有請求後,就調用generate_verification_code()
返回一個驗證碼圖片的url和驗證碼文本,而後將驗證碼保存在session中。
每次驗證表單後,驗證表單中輸入的驗證碼時候和session
中的一致
按條件返回模板
代碼以下:
@user.route('/register', methods=['GET', 'POST']) def register(): form = RegisterForm() if form.validate_on_submit(): username = form.username.data print username if get_user(username): print '帳號已被註冊' flash(u'帳號已被註冊') code_img, code_text = generate_verification_code() session['code_text'] = code_text return render_template('user/register.html', form=form, code_img=code_img) if 'code_text' in session and session['code_text'] != form.verification_code.data: code_img, code_text = generate_verification_code() session['code_text'] = code_text return render_template('user/register.html', form=form, code_img=code_img) email = form.email.data password = form.password.data user = User(username=username, password=password, email=email) try: db.session.add(user) db.session.commit() return redirect(url_for('.index')) except: print traceback.print_exc() db.session.rollback() flash(u'註冊失敗') code_img, code_text = generate_verification_code() session['code_text'] = code_text return render_template('user/register.html', form=form, code_img=code_img) code_img, code_text = generate_verification_code() session['code_text'] = code_text return render_template('user/register.html', form=form, code_img=code_img)
將驗證碼保存在圖片中不是一個號辦法,目前也沒有想到如何保存。