文档章节

Flask开发轻博客(三):Flask 的 Web 表单

AllenOR灵感
 AllenOR灵感
发布于 2017/09/10 01:27
字数 2611
阅读 5
收藏 0

目录

Flask开发轻博客(一):欢迎来到 Flask 的世界

Flask开发轻博客(二):Flask 模板

Flask开发轻博客(三):Flask 的 Web 表单

Flask开发轻博客(四):数据库

Flask开发轻博客(五):用户登录

Flask开发轻博客(六):用户首页和发布博客

Flask开发轻博客(七):分页


上节回顾

上一章中,我们定义了一个简单的模板,使用占位符来虚拟了暂未实现的部分,比如用户以及文章等。

在本章我们将要讲述应用程序的特性之一的表单,我们将会详细讨论如何使用 web 表单。

Web 表单是在任何一个 web 应用程序中最基本的一部分。我们将使用表单允许用户写文章,以及登录到应用程序中。

我们接下来讲述的正是我们上一章离开的地方,所以你可能要确保应用程序 micblog 正确地安装和工作。

一、Flask表单初始化

1. 配置

为了能够处理 web 表单,我们将使用 Flask-WTF,该扩展封装了 WTForms并且恰当地集成进 Flask 中。

许多 Flask 扩展需要大量的配置,因此我们将要在 microblog/ 文件夹下创建一个配置文件以至于容易被编辑。这就是我们将要开始的(文件 config.py ):

    CSRF_ENABLED = True
    SECRET_KEY = 'chen_h'

十分简单,我们的 Flaks-WTF 扩展只需要两个配置。CSRF_ENABLED 配置是为了激活 跨站点请求伪造 保护。在大多数情况下,你需要激活该配置使得你的应用程序更安全些。

SECRET_KEY 配置仅仅当 CSRF 激活的时候才需要,它是用来建立一个加密的令牌,用于验证一个表单。当你编写自己的应用程序的时候,请务必设置一个很难被猜测到的密钥。

既然我们有了配置文件,我们需要告诉 Flask 去读取以及使用它。我们可以在 Flask 应用程序对象被创建后去做,方式如下(文件 app/__init__.py ):

    from flask import Flask

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

    from app import views

1. 用户登录表单

在 Flask-WTF 中,表单是表示成对象,Form 类的子类。一个表单子类简单地把表单的域定义成类的变量。 我们将要创建一个登录表单,用于用户认证系统。在我们应用程序中支持的登录机制是标准的用户名/密码类型 我们同时在表单上提供一个 remember me 的选择框,以至于用户可以选择在他们的网页浏览器上种植 cookie ,当他们再次访问的时候,浏览器能够记住他们的登录。

所以让我们编写第一个表单(文件 app/forms.py ):

    from flask_wtf import Form
    from wtforms import TextField, BooleanField, PasswordField
    from wtforms.validators import Required

    class LoginForm(Form):
        name = TextField('Name', validators=[Required()])
        password = PasswordField('password', validators=[Required()])
        remember_me = BooleanField('Remember_me', default=False)

我相信这个类不言而明。我们导入 Form 类,接着导入两个我们需要的字段类,TextFieldBooleanField

Required 是一个验证器,一个函数,它能够作用于一个域,用于对用户提交的数据进行验证。 Required 验证器只是简单地检查相应域提交的数据是否是空。在 Flask-WTF 中有许多的验证器,我们将会在以后看到它们。

2. 表单模板

我们同样需要一个包含生成表单的 HTML 的模板。好消息是我们刚刚创建的 LoginForm 类知道如何呈现为 HTML 表单字段,所以我们只需要集中精力在布局上。这里就是我们登录的模板(文件 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 Name:<br>
            {{form.name(size=80)}}<br>
        </p>
        <p>
            Password:<br>
            {{ form.password }}
        </p>
        <p>{{form.remember_me}} Remember Me?</p>
        <p><input type="submit" value="Sign In"></p>
    </form>
    {% endblock %}

请注意,此模板中,我们重用了 base.html 模板通过 extends 模板继承声明语句。实际上,我们将在所有我们的模板中做到这一点,以确保所有网页的布局一致性。

在我们的模板与常规的 HTML 表单之间存在一些有意思的不同处。模板期望一个实例化自我们刚才创建地表单类的表单对象储存成一个模板参数,称为 form。当我们编写渲染这个模板的视图函数的时候,我们将会特别注意传送这个模板参数到模板中。

form.hidden_tag() 模板参数将被替换为一个隐藏字段,用来是实现在配置中激活的 CSRF 保护。如果你已经激活了 CSRF,这个字段需要出现在你所有的表单中。

我们表单中实际的字段也将会被表单对象渲染,你只必须在字段应该被插入的地方指明一个 {{form.field_name}} 模板参数。某些字段是可以带参数的。在我们的例子中,我们要求表单生成一个 80 个字符宽度的 name 字段。

因为我们并没有在表单中定义提交按钮,我们必须按照普通的字段来定义。提交字段实际并不携带数据因此没有必要在表单类中定义。

3. 表单视图

在我们看到我们表单前的最后一步就是编写渲染模板的视图函数的代码。

实际上这是十分简单因为我们只需要把一个表单对象传入模板中。这就是我们新的视图函数(文件 app/views.py ):

    from flask import render_template, flash, redirect
    from forms import LoginForm
    from app import app


    # 这里省略了索引函数

    @app.route('/login', methods = ['GET', 'POST'])
    def login():
        form = LoginForm()
        return render_template('login.html', 
            title = 'Sign In',
            form = form)

所以基本上,我们已经导入 LoginForm 类,从这个类实例化一个对象,接着把它传入到模板中。这就是我们渲染表单所有要做的。

让我们先忽略 flash 以及 redirect 的导入。我们会在后面介绍。

这里唯一的新的知识点就是路由装饰器的 methods 参数。参数告诉 Flask 这个视图函数接受GET和POST请求。如果不带参数的话,视图默认只接受GET
请求。

这个时候你可以尝试运行应用程序,在浏览器上看看表单。在你运行应用程序后,你需要在浏览器上打开 http://127.0.0.1:9999/login

我们暂时还没有编写接收数据的代码,因此此时按提交按钮不会有任何作用。


实验效果图

二、表单数据

1. 接收表单数据

Flask-WTF 使得工作变得简单的另外一点就是处理提交的数据。这里是我们登录视图函数更新的版本,它验证并且存储表单数据 (文件 app/views.py ):

    @app.route('/login', methods = ['GET', 'POST'])
    def login():
        form = LoginForm()
        if form.validate_on_submit():
            flash('Login requested for Name: ' + form.name.data)
            flash('passwd: ' + str(form.password.data))
            flash('remember_me: ' + str(form.remember_me.data))
            return redirect('/index')
        return render_template('login.html', 
                               title = 'Sign In',
                               form = form)

如果 validate_on_submit 在表单提交请求中被调用,它将会收集所有的数据,对字段进行验证,如果所有的事情都通过的话,它将会返回 True,表示数据都是合法的。这就是说明数据是安全的,并且被应用程序给接受了。

如果至少一个字段验证失败的话,它将会返回 False,接着表单会重新呈现给用户,这也将给用户一次机会去修改错误。我们将会看到当验证失败后如何显示错误信息。

validate_on_submit 返回 True,我们的登录视图函数调用了两个新的函数,导入自 Flask。flash函数是一种快速的方式下呈现给用户的页面上显示一个消息。在我们的例子中,我将会使用它来调试,因为我们目前还不具备用户登录的必备的基础设施,相反我们将会用它来显示提交的数据。flash函数在生产服务器上也是十分有作用的,用来提供反馈给用户有关的行动。

闪现的消息将不会自动地出现在我们的页面上,我们的模板需要加入展示消息的内容。我们将添加这些消息到我们的基础模板中,这样所有的模板都能继承这个函数。这是更新后的基础模板(文件 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>

显示闪现消息的技术是不言自明的。

在我们登录视图这里使用的另外一个新的函数就是redirect。这个函数告诉网页浏览器引导到一个不同的页面而不是请求的页面。在我们的视图函数中我们用它重定向到前面已经完成的首页上。要注意地是,闪现消息将会显示即使视图函数是以重定向结束。

2. 加强字段验证

现阶段的应用程序,如果表单提交不合理的数据将不会被接受。相反,会返回表单让用户提交合法的数据。这确实是我们想要的。

然后,好像我们缺少了一个提示用户表单哪里出错了。幸运的是,Flask-WTF 也能够轻易地做到这一点。

当字段验证失败的时候, Flask-WTF 会向表单对象中添加描述性的错误信息。这些信息是可以在模板中使用的,因此我们只需要增加一些逻辑来获取它。

这就是我们含有字段验证信息的登录模板(文件 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 Name:<br>
            {{form.name(size=80)}}<br>
            {% for error in form.errors.name %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}<br>
        </p>
        <p>
            Password:<br>
            {{form.pawword}}<br>
            {% for error in form.errors.password %}
            <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 %}

3. 最终效果图

如果你成功运行了上面的程序,那么你可以得到如下的效果图。


网页效果图

本文转载自:http://www.jianshu.com/p/fe096796d8a8

共有 人打赏支持
AllenOR灵感
粉丝 10
博文 2634
码字总数 82983
作品 0
程序员
《Flask Web开发:基于Python的Web应用开发实战》.PDF

简介 本书不仅适合初级Web开发人员学习阅读,更是Python程序员用来学习高级Web开发技术的优秀参考书。 • 学习Flask应用的基本结构,编写示例应用; • 使用必备的组件,包括模板、数据库、W...

jackmk
2017/08/12
0
0
好书推荐.flask.>

图书封面: 书籍简介: 1. 学习Flask应用的基本结构,编写示例应用; 使用必备的组件,包括模板,数据库,Web表单和电子邮件支持; 使用包和模块构建可伸缩的大型应用; 实现用户认证,角色和个人资...

满满李
2016/06/03
97
0
Python进阶(五十三)-Flask Web开发实现将表单渲染成HTML

Python进阶(五十三)-Flask Web来发实现将表单渲染成HTML   在利用Flask进行Python Web开发时,页面中的wtf.quick_form(form)函数中的参数form是如何与视图函数中的form变量关联起来的?即F...

sunhuaqiang1
2017/05/31
0
0
看完这篇文章还能不懂Flask这种Web框架吗?

Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基...

lemonwater
05/14
0
0
Flask插件与资源整理

flask-script 支持命令行选相 使用示例 flask-bootstrap 集成Bootstrap flask-moment 本地化日期和时间 flask-wtf网络表单类防止跨站伪请求CSRF flask-sqlalchemy数据库框架ORM或ODM转换 数据...

晴难自控
2017/11/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

kernel version does not match DSO version

错误信息: kernel version 384.11 does not match DSO version 384.130.0 原因是: cuda driver版本太低,不匹配DSO 简单有效的修复方法,升级nvidia driver, 步骤如下: 1. google seach ...

刘小米
今天
0
0
maven坐标和依赖

一、maven坐标详解 <groupId>com.fgt.club</groupId><artifactId>club-common-service-facade</artifactId><version>3.0.0</version><packaging>jar</packaging> maven的坐标元素说......

老韭菜
今天
1
0
springmvc-servlet.xml配置表功能解释

问:<?xml version="1.0" encoding="UTF-8" ?> 答: xml version="1.0"表示是此xml文件的版本是1.0 encoding="UTF-8"表示此文件的编码方式是UTF-8 问:<!DOCTYPE beans PUBLIC "-//SPRING//......

隐士族隐逸
今天
1
0
基于TP5的微信的公众号获取登录用户信息

之前讲过微信的公众号自动登录的菜单配置,这次记录一下在TP5项目中获取自动登录的用户信息并存到数据库的操作 基本的流程为:微信设置自动登录的菜单—>访问的URL指定的函数里获取用户信息—...

月夜中徘徊
今天
0
0
youTrack

package jetbrains.teamsys.license.runtime; 计算lis package jetbrains.ring.license.reader; 验证lis 安装后先不要生成lis,要把相关文件进行替换 ring-license-checker-1.0.41.jar char......

max佩恩
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部