## Web 表单 配置 为了能够处理 web 表单,我们将使用 Flask-WTF ,该扩展封装了 WTForms 并且恰当地集成进 Flask 中。 许多 Flask 扩展需要大量的配置,因此我们将要在 microblog 文件夹的根目录下创建一个配置文件以至于容易被编辑。这就是我们将要开始的(文件 config.py): $ config.py > CSRF_ENABLED = True > SECRET_KEY = 'you-will-never-guess' // 告诉 Flask 去读取配置文件 app/__init__.py > from flask import Flask > > app = Flask(__name__) > app.config.from_object('config') > > from app import views ## 用户登录表单 在 Flask-WTF 中,表单是表示成对象,Form 类的子类。一个表单子类简单地把表单的域定义成类的变量。 我们将要创建一个登录表单,用户用于认证系统。在我们应用程序中支持的登录机制不是标准的用户名/密码类型,我们将使用 OpenID。OpenIDs 的好处就是认证是由 OpenID 的提供者完成的,因此我们不需要验证密码,这会让我们的网站对用户而言更加安全。 OpenID 登录仅仅需要一个字符串,被称为 OpenID。我们将在表单上提供一个 ‘remember me’ 的选择框,以至于用户可以选择在他们的网页浏览器上种植 cookie ,当他们再次访问的时候,浏览器能够记住他们的登录。 $ vim app/forms.py > from flask.ext.wtf import Form > from wtforms import StringField, BooleanField > from wtforms.validators import DataRequired > > class LoginForm(Form): > openid = StringField('openid', validators=[DataRequired()]) > remember_me = BooleanField('remember_me', default=False) ## 表单模板 $ vim app/templates/login.html > <!-- extend from base layout --> > {% extends "base.html" %} > > {% block content %} > <h1>Sign In</h1> > <form action="" method="post" name="login"> > {{form.hidden_tag()}} > <p> > Please enter your OpenID:<br> > {{form.openid(size=80)}}<br> > </p> > <p>{{form.remember_me}} Remember Me</p> > <p><input type="submit" value="Sign In"></p> > </form> > {% endblock %} ## 表单视图 $ vim app/views.py > from flask import render_template, flash, redirect > from app import app > from .forms import LoginForm > > # index view function suppressed for brevity > > @app.route('/login', methods = ['GET', 'POST']) > def login(): > form = LoginForm() > return render_template('login.html', > title = 'Sign In', > form = form) ## 接收表单数据 // 验证表达数据是否正确(form.validate_on_submit),调用flash()显示消息 $ vim app/views.py > @app.route('/login', methods = ['GET', 'POST']) > def login(): > form = LoginForm() > if form.validate_on_submit(): > flash('Login requested for OpenID="' + form.openid.data + '", remember_me=' + str(form.remember_me.data)) > return redirect('/index') > return render_template('login.html', > title = 'Sign In', > form = form) // flash显示消息 $ vim app/templates/base.html <html> <head> {% if title %} <title>{{title}} - microblog</title> {% else %} <title>microblog</title> {% endif %} </head> <body> <div>Microblog: <a href="/index">Home</a></div> <hr> {% with messages = get_flashed_messages() %} {% if messages %} <ul> {% for message in messages %} <li>{{ message }} </li> {% endfor %} </ul> {% endif %} {% endwith %} {% block content %}{% endblock %} </body> </html> ## 加强字段验证 $ vim app/templates/login.html > <!-- extend base layout --> > {% extends "base.html" %} > > {% block content %} > <h1>Sign In</h1> > <form action="" method="post" name="login"> > {{ form.hidden_tag() }} > <p> > Please enter your OpenID:<br> > {{ form.openid(size=80) }}<br> > {% for error in form.openid.errors %} > <span style="color: red;">[{{ error }}]</span> > {% endfor %}<br> > </p> > <p>{{ form.remember_me }} Remember Me</p> > <p><input type="submit" value="Sign In"></p> > </form> > {% endblock %} ## 处理 OpenIDs $ vim config.py > OPENID_PROVIDERS = [ > { 'name': 'Google', 'url': 'https://www.google.com/accounts/o8/id' }, > { 'name': 'Yahoo', 'url': 'https://me.yahoo.com' }, > { 'name': 'AOL', 'url': 'http://openid.aol.com/<username>' }, > { 'name': 'Flickr', 'url': 'http://www.flickr.com/<username>' }, > { 'name': 'MyOpenID', 'url': 'https://www.myopenid.com' }] $ vim app/view.py > return render_template('login.html', > title = 'Sign In', > form = form, > providers = app.config['OPENID_PROVIDERS']) $ vim app/templates/login.html) > <!-- extend base layout --> > {% extends "base.html" %} > > {% block content %} > <script type="text/javascript"> > function set_openid(openid, pr) > { > u = openid.search('<username>') > if (u != -1) { > // openid requires username > user = prompt('Enter your ' + pr + ' username:') > openid = openid.substr(0, u) + user > } > form = document.forms['login']; > form.elements['openid'].value = openid > } > </script> > <h1>Sign In</h1> > <form action="" method="post" name="login"> > {{ form.hidden_tag() }} > <p> > Please enter your OpenID, or select one of the providers below:<br> > {{ form.openid(size=80) }} > {% for error in form.openid.errors %} > <span style="color: red;">[{{error}}]</span> > {% endfor %}<br> > |{% for pr in providers %} > <a href="javascript:set_openid('{{ pr.url }}', '{{ pr.name }}');">{{ pr.name }}</a> | > {% endfor %} > </p> > <p>{{ form.remember_me }} Remember Me</p> > <p><input type="submit" value="Sign In"></p> > </form> > {% endblock %}