• 5、web表单、重定向和用户会话、flask消息



    **web表单的视图函数和渲染**

    1、安装Flask-WTF
    pip install flask-wtf

     附:

    Flask-WTF插件介绍

    flask-wtf是flask框架的表单验证模块,可以很方便生成表单,也可以当做json数据交互的验证工具,支持热拔插

    flask_wtf完全使用wtfforms组件的字段模型,wtforms对字段的定义在fields模块;又分为core和simple,core模块定义了普通使用的字段,simple在core模块的基础上扩展了一些字段,这些字段会自动进行字段级别的效验

    常用字段说明:

    #core.py

    BooleanField:布尔类型,如Flask,True

    StringField:字符串类型

    DecimalField:小数点文本字段,如‘1.23’

    DateField:日期字段,格式‘%Y-%m-%d’

    DateTimeField:日期字段,格式 '%Y-%m-%d %H:%M:%S'

    FieldList:统一字段类型组成列表   如:FieldList(StringField('Name', [validators.required()]))

    FloatField:浮点数类型

    IntegerField:整型

    SelectMultipleField:多选框

    RadioField:单选框

    #simple.py

    TextAreaField:文本域,可接受多行输入

    PasswordField:密码字段,输入的不会直接在浏览器明文显示

    FileField:上传文件,但不会处理验证文件,需要手动处理

    HiddenField:隐藏字段

    SubmitField:按钮

    TextField:字符串类型的别名,弃用

    字段的验证序列

    字段的参数validators可以指定提交表单的验证序列,按照从左到右的顺序,默认的可选验证在wtforms.validators模块中,已经封装的验证方法有:

    DataRequired/data_required:验证数据是否真实存在,即不能为空,必须是非空白字符串,否则触发StopValidation错误。
    InputRequired/input_required:和DataRequired的区别在于可以是空白字符串;
    Required/required:data_required的别名
    Email/email:验证符合邮件的格式,只有最基本的验证;
    EqualTo/equal_to:比较两个字段的值,比如密码和确认密码,如果不相等就触发错误,equal_to(field,message),需要输入另一个字段的名字。
    IPAddress/ip_address:验证是否是ip地址,默认验证IPV4地址。
    MacAddress/mac_address:验证是否符合mac格式;
    UUID:是否是uuid格式;
    URL/url:验证是否符合url格式;
    Regexp/regexp:用提供的正则表达式验证字段;Regexp(r"")
    Length/length:设置字段值的长度,Length(min,max);
    NumberRange/number_range:设置一个数字字段的取值范围,可以针对浮点数和小数;NumberRange(min,max)
    Optional/optional:允许字段为空并停止验证;
    NoneOf/none_of:将传入的数据和无效的比较,是抛出异常;Noneof(values).
    Anyof/any_of:将传入的数据和预设的数据比较,不是异常。Anyof(values).


    示例:
    导入相应模块
    NameForm表单中有一个名为name的文本字段和一个名为submit的提交按钮
    StringField类表示属性为type="text"的< input>函数
    SubmitField类表示属性为type="submit"的< input>元素
    字段构造函数的第一个参数把表单渲染成HTML时使用的标号
    验证函数Required()确保提交的字段不为空

    实例:
    1、目录结构

    2、在hello.py中修改视图函数,使得能够处理表单

    from flask import Flask,request,make_response,redirect,render_template
    from flask_bootstrap import Bootstrap
    from flask_wtf import Form
    from wtforms import StringField,SubmitField
    from wtforms.validators import Required
    
    app = Flask(__name__)
    app.config["SECRET_KEY"] = "123456"
    bootstrap = Bootstrap(app)
    
    class NameForm(Form):
        name = StringField('what is your name?', validators=[Required()])
        submit = SubmitField('Submit')
    
    @app.route('/', methods=['GET', 'POST'])
    def index():
        name = None
        form = NameForm()
        if form.validate_on_submit():
            name = form.name.data
            form.name.data = ''
        return render_template('index.html', form=form, name=name)
    
    @app.errorhandler(404)
    def page_not_found(e):
        return render_template('404.html'), 404
    
    @app.errorhandler(500)
    def internal_server_error(e):
        return render_template('500.html'), 500
    
    
    @app.route('/user/<name>')
    def user(name):
        return render_template('user.html', name=name)
    
    
    @app.route('/user/<id>')
    def get_user(id):
        user = load_user(id)
        if not user:
            abort(404)
        return '<h1>Hello, %s</h1>' % user.name
    
    
    if __name__ == '__main__':
        bootstrap.run()

    3、在templates/index.html中使用Flask-WTF和Flask-Bootstrap渲染表单
    模板现在分为两部分,第一部分是页面头部,显示欢迎消息
    Jinja2中的条件语句格式为{%if condition%}...{% else %}...{% endif %}
    如果条件为True,那么渲染if和else指令之间的值。如果条件的计算结果为False,则渲染else和endif之间的值

    {% extends "base.html" %}
    {% import "bootstrap/wtf.html" as wtf%}
    
    {% block title %}Flasky{% endblock %}
    
    {% block page_content %}
    <div class="page-header">
    <h1>Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}</h1>
    </div>
    {{ wtf.quick_form(form)}}
    {% endblock %}

    4、base.html

    {% extends "bootstrap/base.html" %}
    
    {% block title %}Flasky{% endblock %}
    
    {% block navbar %}
    <div class="navbar navbar-inverse" role="navigation">
    <div class="container">
    <div class="navbar-header">
    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
    <span class="sr-only">Toggle navigation</span>
    <span class="icon-bar"></span>
    <span class="icon-bar"></span>
    <span class="icon-bar"></span>
    </button>
    <a class="navbar-brand" href="/">Flask</a>
    </div>
    <div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
    <li><a href="/">Home</a></li>
    </ul>
    </div>
    </div>
    </div>
    {% endblock %}
    
    {% block content %}
    <div class="container">
    <div class="page-header">
    {% block page_content %}{% endblock %}
    </div>
    </div>
    {% endblock %}

    5、结果


    当提交空表单时,Required()验证函数会捕获这个错误

    **重定向和用户会话**

    当提交名字后,再重新刷新页面,会出现告警

    处理该告警方式之一是保证最后一次提交是get请求,会出现的问题是,程序处理POST请求时,使用form.name.data获取用户输入的名字,可是一旦这个请求结束了,数据也就丢失了。因此在重定向时,需要保存这个输入的名字,可以使用session

    总结:

    该能的基本实现流程包括  :通过WTForms插件创建form表单,有一个文本框和提交按钮;通过Flask-Bootstrip插件将form表单渲染为HTML页面;为了访问这个页面,通过定义视图函数建立后台表单处理逻辑,返回HTML页面所需参数

    1、修改hello.py,重定向和用户会话

    推荐使用url_for()生成URL,因为这个函数使用URL映射生成URL,从而保证URL和定义的路由兼容,而修改路由的名字后依然可以使用

    使用session.get('name')获取字典中键对应的值以避免未找到键的异常情况,对于不存在的键,get()会返回默认值None

    from flask import Flask,request,make_response,redirect,render_template,session,url_for
    
    @app.route('/', methods=['GET', 'POST'])
    def index():
        form = NameForm()
        if form.validate_on_submit():
            session['name'] = form.name.data
            return redirect(url_for('index'))
        return render_template('index.html', form=form, name=session.get('name'))

    提交名字后再次刷新,没有告警信息

    **flash消息**

    请求完成,可以通过确认消息,告警或错误提示,告诉用户状态的变化
    当用户提交了一项有错误的登录表单后,服务器发回的响应重新渲染了登录表单,并在表单上显示一个消息,提示用户名或密码错误

    1、修改hello.py,实现flash

    @app.route('/', methods=['GET', 'POST'])
    def index():
        form = NameForm()
        if form.validate_on_submit():
            old_name = session.get('name')
            if old_name is not None and old_name != form.name.data:
                flash('Looks like you have changed your name!')
            session['name'] = form.name.data
            return redirect(url_for('index'))
        return render_template('index.html', form = form, name = session.get('name'))

    2、修改templates/base.html,渲染Flash消息
    Flask把get_flashed_messages()函数开放给模板,用来获取并渲染消息

    在模板中使用循环是因为在之前的请求循环中每次调用 flash() 函数时都会生成一个消息,
    所以可能有多个消息在排队等待显示。 get_flashed_messages() 函数获取的消息在下次调
    用时不会再次返回,因此 Flash 消息只显示一次,然后就消失了

    {% block content %}
    <div class="container">
    {% for message in get_flashed_messages() %}
    <div class="alert alert-warning">
    <button type="button" class="close" data-dismiss="alert">&times;</button>
    {{ message }}
    </div>
    {% endfor %}
    
    {% block page_content %}{% endblock %}
    </div>
    {% endblock %}

    3、页面中当两次提交的名字不一样时,会出现告警信息

  • 相关阅读:
    [bzoj3038/3211]上帝造题的七分钟2/花神游历各国_线段树
    [bzoj1002][FJOI2007]轮状病毒_递推_高精度
    UNIX环境高级编程——线程同步之互斥锁、读写锁和条件变量(小结)
    UNIX环境高级编程——线程与进程区别
    UNIX环境高级编程——死锁
    UNIX环境高级编程——线程同步之条件变量以及属性
    UNIX环境高级编程——线程同步之读写锁以及属性
    UNIX环境高级编程——线程同步之互斥量
    UNIX环境高级编程——pthread_create的问题
    UNIX环境高级编程——主线程与子线程的退出关系
  • 原文地址:https://www.cnblogs.com/lw-monster/p/11773497.html
Copyright © 2020-2023  润新知