美文网首页PYTHON收藏FLASK入门Flask实践
Flask实践Step by Step -- Web表单

Flask实践Step by Step -- Web表单

作者: CoderMiner | 来源:发表于2016-10-13 14:15 被阅读550次

    Flask开发环境配置
    Flask快速入门
    Flask实践Step by Step -- 'Hello World'
    Flask实践Step by Step -- 模板
    Flask实践Step by Step -- Web表单

    Flask Web Forms

    上一节我们定义了一个简单的模板,并看到了实际运行的效果,接下来我们来看一下Web表单是如何
    工作的,Web表单是Web应用程序的基础控件,使用表单可以使用用户写博客,进行登录等

    配置

    为了使用表单,我们需要使用Flask的一个扩展插件 Flask-WTF 需要先安装 pip install flask-wtf ,
    许多Flask扩展需要很多的配置,我需要一个配置文件来进行管理 config.py

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

    配置文件中的内容非常简单,需要两项设置即可,WTF_CSRF_ENABLED设置会激活跨站访问保护
    这个设置在这个版本中Flask-WTF是默认打开的,为了更安全我们这里还是显示的设置为 True
    SECRECT_KEY的设置只有当WTF_CSRF_ENABLED为true时才会需要,为表单验证创建一个密码
    token,这个key值尽量设置的复杂一些
    接下来就需要Flask读取相关的配置,并且使用这些配置,在Flask的应用程序创建之后(file app/__init__.py)

    from flask import Flask
    
    app = Flask(__name__)
    app.config.from_object('config')
    
    from app import views
    

    用户登录表单

    Flask-WTF的表单是一个集成基类Form的一个类,现在我们需要创建一个登录的表单,需要用到身份认证系统
    登录机制不是标准的 用户名/密码 模式,我们在这里引入了 OpendID,OpenID本身已经提供了
    很好的验证,我们就不在需要验证密码了,这样可以使网站更安全,需要安装OpenID pip install flask-openid
    使用OpenID登录只需要一个字符串,我们还提供了一个 'remember me' 选择框,用户可以选择是否需要浏览器在cookie中记住
    用户的选择
    写第一个表单 (file 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)
    

    很简单的一个类,继承Form两个字段,StringFieldBooleanField,DataRequired是一个验证器
    一个方法和一个字段绑定,这个DataRequired验证器只是简单的验证提交的输入内容,这Flask-WTF中还有很多
    验证器,后续会继续介绍

    表单模板

    我们需要一个模板来生成HTML的表单,我们需要创建一个新的模板 (file app/templates/login.html)

    {% extends "base.html" %}
    
    {% block content %}
      <h1>Sign in</h1>
      <form class="" action="" name="login" method="post">
        {{form.hidden_tag()}}
        <p>
          Please enter your OpenID:<br>
          {{ form.openid(size=80) }}
        </p>
        <p>
          {{ form.remember_me }} Remember Me
        </p>
        <p>
          <input type="button" value="Sign in" type="submit">
        </p>
      </form>
    {% endblock %}
    
    

    这个模板中同样是继承base.html,这个模板和普通的HTML页面的表单还是有一些区别的,需要
    视图中对应的方法来血染这个模板,form.hidden_tag()会被HTML中的隐藏的域来取代,这个参数
    需要把CSRF设置为Enabled状态

    表单视图

    我们需要一个视图方法来渲染这个模板(file app/views.py)

    from flask import render_template,flash,redirect
    from app import app
    from .forms import LoginForm
    
    #index view function...
    
    @app.route('/login',methods=['GET','POST'])
    def login():
        form = LoginForm()
        return render_template('login.html',
                                title="Sign in",
                                form=form)
    

    需要引入 LoginForm这类,然后实例化,将这个实例化对象作为参数传入到模板中,我们还引入了
    flashredirect,可以暂时忽略这两个引用,以后我们会用到,在装饰器中我们加入了 methods
    作为参数,告诉Flask我们的这个方法接收 GET和POST请求,保存运行,打开浏览器 访问 http://127.0.0.1:5000/login
    看一下实际的效果,暂时我们还没有处理接收数据的处理,所以现在点击提交按钮会没有任何反馈

    接收数据

    Flask-WTF能够很容易处理从客户端发来的数据,我们需要修改一下 login的方法(file app/views.py)

    @app.route('/login',methods=['GET','POST'])
    def login():
        form = LoginForm()
        if form.validate_on_submit():
            flash('Login requested for OpenID=""%s",remember_me=%s'%
                    (form.openid.data,str(form.remember_me.data)))
            return redirect('/index')
        return render_template('login.html',
                                title="Sign in",
                                form=form)
    

    方法 validate_on_submit会处理所有的表单的处理工作,表单展示给用户时会调用这个方法此时会返回 False
    当提交请求时,这个方法会接收所有的数据,验证数据的合法性,如果验证全部正确,这个方法会返回True,只要有一个
    参数验证不通过,这个方法就会返回 False,稍后我们会展示如何给用户展示错误信息,当 validate_on_submit返回True
    时,方法 flash会展示一个快速的信息,在调到下一个页面之前,这个flash的信息不回显示在页面中,我们需要修改模板信息
    来显示这个信息(file app/templates/base.html)

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        {% if title %}
        <title>{{ title }} - microblog</title>
        {% else %}
        <title>Welcome to microblog</title>
        {% endif %}
      </head>
      <body>
        <div>
          Microblog : <a href="/index">Home</a>
        </div>
        <hr>
        {% with messages = get_flashed_messages()%}
          {% if messages %}
            <ul>
              {% for msg in messages %}
                <li>{{ msg }}</li>
              {% endfor %}
            </ul>
          {% endif %}
        {% endwith %}
        {% block content %}{% endblock %}
      </body>
    </html>
    
    

    方法get_flashed_messages会接收flash方法发送来的消息,并展示出来,在视图方法中我们还使用另一个
    方法 redirect,这个方法会重定向到另一网页地址

    改进数据的验证

    当用户的输入的信息有误时,希望能够提供给用户友好的错误的信息提示,我们修改一下login的模板(file app/templates/login.html)

    {% extends "base.html" %}
    
    {% block content %}
      <h1>Sign in</h1>
      <form class="" action="" name="login" method="post">
        {{form.hidden_tag()}}
        <p>
          Please enter your OpenID:<br>
          {{ form.openid(size=80) }}
          {% for error in form.openid.errors %}
            <span style="color:red;">[{{ error }}]</span>
          {% endfor %}
        </p>
        <p>
          {{ form.remember_me }} Remember Me
        </p>
        <p>
          <input value="Sign in" type="submit">
        </p>
      </form>
    {% endblock %}
    

    添加了错误的提示信息

    处理OpenIDs

    为了是用户更容易的登录网站,我们添加一些openid的连接,儿不需要用户手动的输入OpenID
    先定义一些OpenID的提供者,定义在config.py

    WTF_CSRF_ENABLED = True
    SECRET_KEY = 'you-will-never-guess'
    
    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'}]
    
    

    然后在视图方法中使用

    @app.route('/login',methods=['GET','POST'])
    def login():
        form = LoginForm()
        if form.validate_on_submit():
            flash('Login requested for OpenID=""%s",remember_me=%s'%
                    (form.openid.data,str(form.remember_me.data)))
            return redirect('/index')
        return render_template('login.html',
                                title="Sign in",
                                form=form,
                                providers=app.config['OPENID_PROVIDERS'])
    

    还需要修改对应的模板视图(file app/templates/login.html)

    {% extends "base.html" %}
    
    {% block content %}
    
    <script type="text/javascript">
      function set_openid(openid,pr){
        u = openid.search('<username>')
        if(u != -1){
          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 class="" action="" name="login" method="post">
        {{form.hidden_tag()}}
        <p>
          Please enter your OpenID:<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 value="Sign in" type="submit">
        </p>
      </form>
    {% endblock %}
    
    
    运行截图

    写在最后

    我们队登录的表单做了很多的改进,但是我们还没有真正的登录到系统中,真正的登录我们需要后台的数据库的支持

    相关文章

      网友评论

        本文标题:Flask实践Step by Step -- Web表单

        本文链接:https://www.haomeiwen.com/subject/pumwyttx.html