Flask 教程,第三部分:Web 表单 已翻译 100%

oschina 投递于 2012/12/28 09:03 (共 22 段, 翻译完成于 01-08)
阅读 67720
收藏 13
4
加载中

这是我撰写的关于利用基于python的flask框架开发web应用系列文章的第3部分。

该系列文章的目的是建立一个功能完善的微博应用,我决定称它为microblog,虽然这个名字没什么创意。(引用第2部分翻译)

一下是该系列所有已发布文章的索引:


linnchord
翻译于 2013/01/05 11:23
3

概要

在前面章节我们为主页定义了一个简单的模板,部分尚未实现的模块如用户或帖子等使用模拟的对象作为临时占位。

本章我们将看到如何利用web表单填补这些空白。

web表单是web应用中最基本的构建要素,我们将通过表单来实现用户发帖和应用登录功能

完成本章内容你需要基于前面章节完成的微博应用代码,请确认这些代码已安装并能正常运行。

linnchord
翻译于 2013/01/05 12:41
3

配置

Flask-WTFWTForms项目的Flask框架扩展,我们将用他来帮助我们处理web表单。

大部分Flask扩展都需要定义相关配置项,所以我们先来在应用根目录下创建一个配置文件以备使用。我们先这样创建 (fileconfig.py):

CSRF_ENABLED = True
SECRET_KEY = 'you-will-never-guess'

很简单吧,这是Flask-WTF需要用到的2个配置项CSRF_ENABLED配置启用了跨站请求攻击保护,大部分情况下你都需要开启此功能,这能使你的应用更安全。

linnchord
翻译于 2013/01/05 15:53
4

SECRET_KEY设置当CSRF启用时有效,这将生成一个加密的token供表单验证使用,你要确保这个KEY足够复杂不会被简单推测。

现在这个配置文件已经基本可用了。项目创建完成我们可以创建如下文件并编辑(fileapp/__init__.py):

from flask import Flask

app = Flask(__name__)
app.config.from_object('config')

from app import views
linnchord
翻译于 2013/01/05 15:59
4

用户登录表单

使用Flask-WTF创建的表单就像一个对象,需要从Form类继承子类。然后在这个子类中定义一些类的属性变量作为表单字段就可以了。

我们要创建一个登录表单,用来进行用户身份识别。但跟平常需要验证用户名和密码的登录方式不同,我们将使用 OpenId 来处理登录过程。使用OpenId的好处就是我们不用管那些用户名和密码的认证过程,交给 OpenId 去搞定,它会返回给我们用户验证后的数据。这样对于使用我们网站的用户而言也更安全。

zzxworld
翻译于 2013/01/07 10:41
2

使用 OpenId 登录只需要一个字符串,然后发送给 OpenId 服务器就行了。另外我们还需要在表单中加一个“记住我” 的选项框,这个是送给那些不想每次来我们网站都要进行身份认证的人。选择这个选项后,首次登录时会用cookie在他们的浏览器上记住他们的登录信息,下次再进入网站时就不需要进行登录操作。

开始我们的第一个表单吧 (fileapp/forms.py):

from flask.ext.wtf import Form, TextField, BooleanField
from flask.ext.wtf import Required

class LoginForm(Form):
    openid = TextField('openid', validators = [Required()])
    remember_me = BooleanField('remember_me', default = False)
欣赏一下这个类,多么的简洁,多么的一目了然。如此简单,但又十分的富有内涵。我们引入了一个 Form 类,然后继承这个类,按需求还添加了 TextField 和 BooleanField 这两个字段。

另外还引入了一个表单验证函数 Required,这种验证函数可以附加在字段里面,在用户提交表单时它们会用来检查用户填写的数据。这个 Required 函数是用来防止用户提交空数据。Flask-WTF 中还有很多不同作用的表单验证函数,我们将会在后面使用到它们。

zzxworld
翻译于 2013/01/07 11:24
2

表单模板

现在我们的问题就是需要一个显示这个登录表单的模板。好消息是我们刚刚创建的登录表单类知道如何把字段转换成HTML,所以我们只需要把注意力集中到页面布局上。下面就是我们的登录表单的模板 (fileapp/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 %}
容我啰嗦一下,在这个模板中,我们又一次使用了模板继承的方式。使用 extends 语句从 base.html 继承模板内容。我们会在后面创建的模板中继续使用这种方式,这样可以使我们所有的页面布局保持一致。
zzxworld
翻译于 2013/01/07 11:39
2

这个登录模板跟普通的HTML表单有些明显的区别,它使用模板参数 {{ ... }} 来实例化表单字段,而表单字段又来源于我们刚刚定义的表单类,模板参数中使用了 form 这个名称。当我们使用视图函数引用表单类并渲染到模板时,我们要特别注意这个把表单类传递到模板的变量名。

我们在配置中开启了CSRF(跨站伪造请求)功能,模板参数 {{ form.hidden_tag() }} 会被替换成一个具有防止CSRF功能的隐藏表单字段。在开启了CSRF功能后,所有模板的表单中都需要添加这个模板参数。

zzxworld
翻译于 2013/01/07 12:45
3

我们定义的表单对象中的字段同样也能被模板渲染,只需要在模板合适的位置添加类似于 {{ form.field_name }} 这样的模板参数,相关字段就会在被定义的位置出现。另外还有一些字段是可以传参数,比如这个 openid 字段,我们就添加了一个参数让它显示的宽度增加到80个字符。

由于我们没有在表单中定义一个提交功能的按钮,所以在这里只能以普通表单字段的方式来做了。不过说起来区区一个按钮,在表单中跟任何数据都没有关系,的确也没有在表单类中定义的必要。

zzxworld
翻译于 2013/01/07 12:57
2

表单视图

见证奇迹的时刻最后一步,我们马上要来写一个渲染登录表单对象到模板的视图函数。

这个函数相当的简单无趣,因为我们只需要把表单对象传递给模板就行了。下面就是我们这个视图函数的全部内容 (fileapp/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)
我们引入登录表单类,然后把它实例化到一个变量,最后再把这个变量传给模板。要渲染表单字段必须的事情也就这些。

上面的代码中还引入了两个新对象: falsh 和 redirect, 这个先甭理它们,稍后才用得上。

zzxworld
翻译于 2013/01/08 13:08
2
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(25)

helloHeng
helloHeng

引用来自“不必在乎朕是谁”的评论

引用来自“zhangdedezhu”的评论

No module named flask.ext.wtf 一直提示这个错误,但是明明在第一步的时候装过了,这是为什么

http://docs.torriacg.org/docs/flask/patterns/wtforms.html
貌似这个包变成了 WTForms
尝试这样或许可行
from flask_wtf import FlaskForm
风过暖城
风过暖城

引用来自“jeffsui”的评论

问题解决了,flask0.9版本之后,需要安装flask-wtf和WTForms,然后修改导入的包:
from flask.ext.wtf import Form
from wtforms.fields import TextField,StringField,BooleanField
from wtforms.validators import DataRequired
就可以了

引用来自“夜不成寐”的评论

运行以后报错views.py,No module named 'forms',明明forms.py 和views.py是放在同一目录下的,求解
在view.py中应该是from .forms import LoginForm
夜不成寐
夜不成寐

引用来自“jeffsui”的评论

问题解决了,flask0.9版本之后,需要安装flask-wtf和WTForms,然后修改导入的包:
from flask.ext.wtf import Form
from wtforms.fields import TextField,StringField,BooleanField
from wtforms.validators import DataRequired
就可以了
运行以后报错views.py,No module named 'forms',明明forms.py 和views.py是放在同一目录下的,求解
jeffsui
jeffsui
问题解决了,flask0.9版本之后,需要安装flask-wtf和WTForms,然后修改导入的包:
from flask.ext.wtf import Form
from wtforms.fields import TextField,StringField,BooleanField
from wtforms.validators import DataRequired
就可以了
c
code_cheers

引用来自“罗泽轩”的评论

原文中的:
from flask.ext.wtf import Form, TextField, BooleanField
from flask.ext.wtf import Required
在flask-wtf的0.9版之后已经不可用。
见 https://flask-wtf.readthedocs.org/en/latest/upgrade.html#version-0-9-0
0.9版之后的flask-wtf的结构有了不小的改动,如果遇到问题,可以先去看看官方文档。
新版本用这种方式引用: from flask.ext.wtf import Form from wtforms.fields import TextField,BooleanField from wtforms.validators import Required
litao6015
litao6015

引用来自“zhangdedezhu”的评论

引用来自“不必在乎我是谁”的评论

引用来自“zhangdedezhu”的评论

No module named flask.ext.wtf 一直提示这个错误,但是明明在第一步的时候装过了,这是为什么

http://docs.torriacg.org/docs/flask/patterns/wtforms.html
貌似这个包变成了 WTForms

我建议你还是看原版英文文档,好多问题都可以避免的
这个的英文原版在哪儿呢,能发个链接吗?
X-Alvin
X-Alvin

引用来自“X-Alvin”的评论

登入login显示:unbound method hidden_tag() must be called with LoginForm instance as first argument (got nothing instead)怎么解决啊,我知道是实例化的问题,不过form不是已经是实例化的了么
已解决,代码有误,sorry
X-Alvin
X-Alvin
登入login显示:unbound method hidden_tag() must be called with LoginForm instance as first argument (got nothing instead)怎么解决啊,我知道是实例化的问题,不过form不是已经是实例化的了么
爱已欠费停机

引用来自“罗泽轩”的评论

原文中的:
from flask.ext.wtf import Form, TextField, BooleanField
from flask.ext.wtf import Required
在flask-wtf的0.9版之后已经不可用。
见 https://flask-wtf.readthedocs.org/en/latest/upgrade.html#version-0-9-0
0.9版之后的flask-wtf的结构有了不小的改动,如果遇到问题,可以先去看看官方文档。

引用来自“爱已欠费停机”的评论

ImportError: No module named flask.ext.wtf 报这错的时候得装这个 pip install -U Flask-WTF 接着把forms.py这里改为 from flask.ext.wtf import Form from wtforms import TextField, BooleanField from wtforms.validators import Required 及可运行
看我的回复可以解决
爱已欠费停机

引用来自“罗泽轩”的评论

原文中的:
from flask.ext.wtf import Form, TextField, BooleanField
from flask.ext.wtf import Required
在flask-wtf的0.9版之后已经不可用。
见 https://flask-wtf.readthedocs.org/en/latest/upgrade.html#version-0-9-0
0.9版之后的flask-wtf的结构有了不小的改动,如果遇到问题,可以先去看看官方文档。
ImportError: No module named flask.ext.wtf 报这错的时候得装这个 pip install -U Flask-WTF 接着把forms.py这里改为 from flask.ext.wtf import Form from wtforms import TextField, BooleanField from wtforms.validators import Required 及可运行
返回顶部
顶部