zoukankan      html  css  js  c++  java
  • flask 在视图函数中验证表单 --

    在视图函数中验证表单

    因为现在的basic_form视图同时接受两种类型的请求:GET请求和POST请求。所以我们要根据请求方法的不同执行不同的代码。具体来说,首先是实例化表单,如果是GET请求,就渲染模板;如果是POST请求,就调用validate()方法验证表单数据。

    请求的HTTP方法可以通过requeset.method属性获取,我们可以使用下面的方式来组织视图函数:

    from flask import request
    
    @app.route('/basic', methods=['GET','POST'])
    def basic():
        form = LoginForm() #GET + POST
        #如果用户提交表单,并且数据通过验证
        if request.method == 'POST' and form.validate():
        #获取表单数据并保存
            ...#处理POST请求
        return render_template('forms/basic.html',form=form)  #处理GET请求

    当请求方法是GET时,会跳过这个if语句,渲染basic.html模板;当请求的方法是POST时(说明用户提交了表单),则验证表单数据。这会逐个字段(包括CSRF令牌字段)调用附加的验证器进行验证。

    因为WTForms会自动对CSRF令牌字段进行验证,如果没有渲染该字段会导致验证出错,错误消息为”CSRF token is missing”。

    Flask-WTF提供的validate_on_submit()方法合并了这两个操作(判断请求方法和验证表单字段),因此上面的代码可以简化为:

    @app.route('/basic', methods=['GET','POST'])
    def basic():
        form = LoginForm()
        if form.validate_on_submit():
            ...
        return render_template('basic.html', form=form)

    除了POST方法,如果请求的方法是PUT、PATCH和DELETE方法,form.validate_on_submit()也会验证表单数据。

    如果form.validate_on_submit()返回True,则表示用户提交了表单,且表单通过验证,那么我们就可以在这个if语句内获取表单数据,比如:

    from flask import Flask, render_template, redirect, url_for, flash
    
    @app.route('/basic', methods=['GET', 'POST'])
    def basic():
        form = LoginForm()
        if form.validate_on_submit():
            username = form.username.data
            flash('Welcom home, %s!' % username)
            return redirect(url_for('hello'))
        return render_template('basic.html', form = form)
    
    @app.route('/hello')
    def hello():
        return render_template('hello.html')
    表单类的data属性是一个匹配所有字段与对应数据的字典,我们一般直接通过”form.字段属性名.data”的形式来获取对应字段的数据。例如,form.username.data返回username字段的值。在代码中,当表单验证成功后,我们获取了username字段的数据,然后用来发送一条flash消息,最后将程序重定向到hello视图。
    表单的数据一般会存储到数据库中,在这里将数据填充到flash()函数里。
    先访问127.0.0.1:5000/basic

    
    
    输入表单内容,点击提交,触发validate_on_submit()方法
    发送闪现消息
    闪现消息在重定向后的hello页面显示

    
    
    程序的逻辑是:访问/basic页面,提交了表单后,触发了视图函数里的表单验证逻辑,之后flash了消息,然后重定向到hello视图(页面重定向到/hello地址),在hello页面显示了flash消息
     
    在basic模板中定义了表单,继承了base模板:
    basic.html:
    {% extends 'base.html' %}
    {% block content %}
    <form method="post">
        {{ form.csrf_token }}<!-- 渲染CSRF令牌隐藏字段 -->
        {{ form.username.label }}{{ form.username }}<br>
        {{ form.password.label }}{{ form.password }}<br>
        {{ form.remember }}{{ form.remember.label }}<br>
        {{ form.submit }}<br>
    </form>
    {% endblock %}

    同时hello.html模板也继承了basic模板,在basic模板中有get_flashed_messages()方法来处理flash消息,使得basic视图的flash消息能够在重定向到hello.html模板时可以在页面显示
    base.html模板:
     
    <!DOCTYPE html>
    <html lang="en">
    <head>
        {% block head %}
            {% block metas %}
                <meta charset="utf-8">
            {% endblock metas %}
            <title>
                {% block title %}
                    Form - HelloFlask
                {% endblock title %}
            </title>
            <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='favicon.ico') }}">
            {% block styles %}
                <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
            {% endblock styles %}
        {% endblock head %}
    </head>
    <body>
    <nav>
        {% block nav %}
            <ul>
                <li><a href="{{ url_for('basic') }}">Home</a></li>
            </ul>
        {% endblock %}
    </nav>
    
    <main>
        {% for message in get_flashed_messages() %}
            <div class="alert">
                {{ message }}
            </div>
        {% endfor %}
        {% block content %}{% endblock %}
    </main>
    <footer>
        {% block footer %}
            <small> &copy; 2019 <a href="https://www.cnblogs.com/xiaxiaoxu/" title="xiaxiaoxu's blog">夏晓旭的博客</a> /
                <a href="https://github.com/xiaxiaoxu/hybridDrivenTestFramework" title="Contact me on GitHub">GitHub</a> /
                <a href="http://helloflask.com" title="A HelloFlask project">Learning from GreyLi's HelloFlask</a>
            </small>
        {% endblock %}
    </footer>
    {% block scripts %}{% endblock %}
    </body>
    </html>
    hello.html模板:
     
    {% extends 'base.html' %}
    {% block content %}
    <title>Hello from Flask</title>
    <ul>
        <li><a href="{{ url_for('hello') }}">xiaxiaoxu</a></li>
    </ul>
    {% endblock %}
  • 相关阅读:
    linux命令总结
    在阿里云centos7.6上部署vue.js2.6前端应用
    MongoDb语法
    Echarts 地图绘制
    在阿里云Centos7.6中部署nginx1.16+uwsgi2.0.18+Django2.0.4
    django--- 支付宝退款
    响应式网站设计(Responsive Web design)
    django -- 推荐商品算法
    django -- 美多订单分表
    小程序基本配置
  • 原文地址:https://www.cnblogs.com/xiaxiaoxu/p/10513776.html
Copyright © 2011-2022 走看看