zoukankan      html  css  js  c++  java
  • Flask入门 表单Flask-wtf form原生 Bootstrap渲染(七)

    (1) 原生的表单

    模板页面,form表单form.html

    <form action="{{ url_for('/check/') }}" method='post'>
    	<p>用户名: <input type='text' name='username'></p>
        <p>密码: <input type='password' name='userpass'></p>
        <p><input type='submit' value='submit'></p>
    </form>
    

    在manage.py中

    #原生表单
    @app.route('/form')
    def form():
        return render_template('form.html')
    
    #获取原生表单提交的数据
    @app.route('/check',method=['POST'])
    def check():
        print(request.form.get('userpass'))
        print(request.form.get('username'))
        return '提交数据'
    #注: 第一个form函数仅仅是跳转页面作用,比较浪费因此我们可以合并一下
    

    在manage.py中将路由函数合并

    @app.route('/form')
    def form():
      if request.method == 'POST':
        print(request.form.get('userpass'))
        print(request.form.get('username'))
      return render_template('/form.html')
    

    (2) Flask-wtf表单

    说明 : 是一个用于表单处理,校验并提供csrf验证的功能的扩展库

    **安装 **:

    sudo pip3 install flask-wtf
    

    作用: Flask-wtf能保护所有表单免受跨站请求伪造的攻击(Cross-Site Request Forgery,CSRF),恶意网站会把请求发送到被攻击者登录的其他网站就会引起CSRF攻击,因此我们需要实现CSRF保护机制,Flask-wtf采用的做法是为程序设置一个秘钥,Flask-WTF 使用这个密钥生成加密令牌,再用令牌验证请求中表单数据的真伪。

    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'sadad131[]'
    #采用字典的方式存储框架,扩展和程序本身的配置变量,一般秘钥不直接写入代码,放在环境变量增加安全性.
    

    flask-wtf一般自定义的表单类都是继承自Form类或者其子类,一般有表单类,验证器类

    1. 表单类主要有以下几种:
    字段类型 字段说明
    StringField 普通文本字段
    TextAreaField 多行文本字段
    SubmitField 提交
    PasswordField 密码字段
    HiddenField 隐藏文本字段
    DateField 日期字段 datetime.date(year=2018,month=2,day=20)
    2018-02-20
    DateTimeFiled 时间字段 datetime.datetime(year=2018,month=2,day=20)
    2018-02-20 00:00:00
    IntegerField 文本字段,值为整数
    FloatField 文本字段,值是浮点数
    DecimalField 文本字段,值为 decimal.Decimal
    BooleanField 复选框,值为 True 和 False
    RadioField 一组单选框 choices = [('w','女'),('m','男')] 参数1作为传递,参数2位显示值
    SelectField 下拉列表 choices参数确定了下拉选项, 是一个tuple组成的列表 (同上)
    SelectMultipleField 下拉列表,可选择多个值
    FileField 文件上传字段
    FormField 把表单作为字段嵌入另一个表单

    ​ Validator是验证函数,把一个字段绑定验证函数之后,flask在接受表单之前会做一个验证 , 如果验证成功才会接收数据。验证函数Validator如下,

    2 验证器一般有以下几种:

    • 基本上每一个validator都有message参数,指出当输入数据不符合validator要求时显示什么信息
    验证器函数 说明
    DataRequired/Required 代表内容是必填项 DataRequired(message='用户信息不能为空')
    Email 验证电子邮件地址,要求正则模式 : ^.+@([^.@][^@]+)$
    EqualTo 比较两个字段的值,常用于确认密码情况
    EqualTo('要确认字段名',message='xxx')
    IPAddress 验证IPV4网络地址 参数默认ipv4=True,ipv6=False
    Length 验证输入字符串的长度 参数类型是字符串
    Length(min=6,max=30,message='个人信息的简介6-30个字')
    NumberRange 验证输入的值在数字范围内
    NumberRange(min=6,max=90,message='年龄为6-90岁')
    Optional 无输入值时跳过其他验证函数
    Regexp 使用正则表达式验证输入值 参数regex='正则模式'
    URL 验证 URL URL(message='请输入正确的url地址')]
    正则模式是^[a-z]+://(?P<host>[^/:]+)(?P<port>:[0-9]+)?(?P<path>/.*)?$
    AnyOf 确保输入值在可选值列表中
    NoneOf 确保输入值不在可选值列表中

    实例wtf表单

    模板文件 form.html

    <form action="{{ url_for('wtf_form') }}" method='post'>
    	{{ form.csrf_token }} #进入csrf验证
        <p>{{ form.username.label }}{{ form.username(style='color:red',placeholder='请输入用户名') }}{{ form.username.errors }}</p>
        <p>{{ form.userpass.label }}{{ form.userpass() }}{{ form.userpass.errors }}</p>
        <p>{{ form.submit() }}</p>
    </form>
    
    #通过form.字段名获取对应字段属性    form.字段名(修饰符)
    

    manage.py文件中

    from flask import Flask,render_template,request
    from flask_wtf import FlaskForm   #导入继承父类
    from wtforms import StringField,PasswordField,SubmitField
    from wtforms.validators import Length,DataRequired
    
    class Login(FlaskForm):  #继承自FlaskForm类
        username = StringField('用户名',validators=[Length(min=6,max=12,message='用户名长度为6~12位'),DataRequired(message='用户名不能为空')])
        userpass = PasswordField('密码',validators=[Length(min=6,max=12,message='密码长度为6~12位'),DataRequired(message='密码不能为空')])
        submit = SubmitField('登录')
        
    
    @app.route('/wtf_form',methods=['GET','POST'])
    def wtf_form():
        form = Login()  #实例化form对象
        if request.method == 'POST':
            if form.validate_on_submit():  #数据正确 并且验证csrf通过
                print(request.form.get('userpass'))
                print(request.form.get('username'))
                return '数据提交成功'
        return render_template('wtf_form.html',form=form)
    
    #注:
    #1 methods 参数告诉Flask在URL映射中把这个视图函数注册为GET和POST请求的处理程序,默认GET
    #2 采用post请求可以通过对象很轻松访问,GET 请求没有主体,提交的数据以查询字符串的形式附加到URL中
    #3 validate_on_submit() 会调用username 字段上附属的 DataRequired() 验证函数。
    

    注意: 1 form.validate_on_submit() 只有在数据正确 并且验证csrf通过 返回True

    ​ 2 {{ form.csrf_token }} 进入表单 csrf 验证

    (3) 使用bootstrap快速渲染

    安装

    pip3 install flask-bootstrap
    

    视图函数:导入与实例

    from flask_bootstrap import Bootstrap   #导入
    
    bootstrap = Bootstrap(app)  #绑定bootstrap与该项目app的关系
    

    导入 :基本用到的模板为 base.html 继承基类 和wtf.html 导入宏

    {% import 'bootstrap/wtf.html' as wtf %}  #导入重命名为wtf
    
    {{ wtf.quick_form(form,url_for('index')) }}   #访问宏wtf.quick_form('数据',路由)
    {{ wtf.quick_form(form) }}
    

    ​ 可以使用 Bootstrap 中预先定义好的表单样式渲染整个 Flask-WTF 表单。导入模板中的bootstrap/wtf.html 元素。定义了一个使用 Bootstrap 渲染 Falsk-WTF 表单对象的辅助函数。 wtf.quick_form() 函数的参数为 Flask-WTF 表单对象,使用 Bootstrap 的默认样式渲染传入的表单。

    index.html

    { % extends "base.html" % }   #继承base.html,必须写在最前面
    { % import "bootstrap/wtf.html" as wtf % }   #重命名wtf
    { % block title % }首页{ % endblock % }
    { % block page_content % }  #定义内容
    <div class="page-header">
        <h1>Hello, { % if username % }{{ username }}{ % else % }Stranger{ % endif % }!</h1>
    </div>
    {{ wtf.quick_form(form) }}   #传入表单对象
    { % endblock % }
    

    (4) 重定向和用户会话(Post/重定向/Get 模式)

    基于Web程序把POST请求作为浏览器发送的最后一个请求,这种需求的实现方式是,使用重定向作为 POST 请求的响应,而不是使用常规响应。但是请求结束之后form.username.data接受的数据为用户输入的名字也就丢失了.因此我们采取将数据存储放在用户会话session中.

    from flask import Flask,render_template,session,redirect,url_for
    @app.route('/',methods=['GET','POST'])
    def index():
        form = Login()
        if form.validate_on_submit(): #判断request是个带POST数据,且数据符合表单定义要求
            session['username'] = form.username.data   #将username保存到session
            return redirect(url_for('index'))   #重定向到'index视图函数路由'
        return render_template('index.html',form=form,name=session.get['username'])
    
    #注:  <表单对象名>.<Field名称>.data  可以访问POST请求对应字段数据
    

    (5) Flash消息

    Flask的核心特性Flash实现: 为了解决用户提交了有一项错误的登录表单后,服务器发回的响应重新渲染了登录表单,并在表单上面显示一个消息,提示用户用户名或密码错误。常常用于表单信息提示.

    flash() 作用是每次调用flash()都会触发一个消息所以可能有多个消息在排队等待显示。

    get_flashed_messages() 函数获取传入的消息 其实就是一个列表, 获取的消息在下次调用时不会再次返回,因此 Flash 消息只显示一次,然后就消失了。

    使用

    from flask import flask,get_flashed_messages
    @app.route('/register/',method=['GET','POST'])
    def register():
        form = Register()
        if form.validate_on_submit():
            flash('注册成功')
            return redirect(url_for('index'))
        return render_template('form.html',form=form)
    

    在模板中获取

    {% for message in get_flashed_messages() %}
    	 <div class="alert alert-success alert-dismissible" role="alert">
                <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span
                        aria-hidden="true">&times;</span></button>
                <strong>success!</strong>{{ message }}
         </div>
    {% endfor %}
    

    flash使用当然不仅仅限于单一消息的传递,flash的源码定义为 :

    def flash(message, category='message'):
    

    因此可以看到不仅能传递消息message还能将传递的消息进行类别category选择

    get_flashed_messages同样有接受信息类别的属性with_categories=设置为True

    def get_flashed_messages(with_categories=False, category_filter=[]):
    

    例如

    if content.split('
    ') <= 2:
      flash(message=u'警告',category='warning')
    elif content.split('
    ') >= 5:
      flash(message=u'不允许的操作',category='danger')
    
    {% block content %}
      {% for category,message in get_flashed_message(with_category=True) %}
      <div class="alert alert-{{ category }} alert-dismissable">
        <button type="button" class="close" data-dismiss="alert">&tims;</button>
        {{ message }}
      </div>
      {% endfor %}
    {% endblock %}
    
    #按照分级信息弹出不同的显示框
    
  • 相关阅读:
    Leetcode Spiral Matrix
    Leetcode Sqrt(x)
    Leetcode Pow(x,n)
    Leetcode Rotate Image
    Leetcode Multiply Strings
    Leetcode Length of Last Word
    Topcoder SRM 626 DIV2 SumOfPower
    Topcoder SRM 626 DIV2 FixedDiceGameDiv2
    Leetcode Largest Rectangle in Histogram
    Leetcode Set Matrix Zeroes
  • 原文地址:https://www.cnblogs.com/why957/p/9126061.html
Copyright © 2011-2022 走看看