Flask Web第四章

第四章

4.2使用Flask—WTF处理表单

  1. 默认为每个表单启用CSRF保护,为我们自动生成和验证CSRF令牌

  2. 默认使用程序秘钥对CSRF令牌签名,设置秘钥:app.secret_key = os.getenv('SECRET_KEY', 'secret string')

4.2.1定义表单类

  1. 使用WTForms创建表单时,类要继承从WTForms导入的Form基类

    • 字段属性通过实例化WTForms提供的字段类表示,名称作为对应HTML<input>元素的name属性和id属性。注意:名称大小写敏感,不能以下划线或validate开头

    • 实例化字段类的参数有:

      • label:字段标签<label>的值,也就是渲染后再输入字段前的提示文字

      • render_kw:字典类型,设置<input>标签的属性,如{‘'placeholder':'haha'}

      • validators:列表,包含一系列验证器。验证器是用于验证字段数据的类,从wtforms.validators模块导入。实例化验证类时,message参数传入自定义错误信息

      • default:字符串或可调用对象,给字段设置默认值

  2. 使用Flask—WTF创建表单,要继承FlaskForm类,其他操作与上条一样

4.2.2输出HTML代码

  1. 输出字段的HTML代码,用’form.字段名‘。如:form.username

  2. 输出字段<label>的代买,用"form.字段名.label".如:form.username.label

  3. 给字段增加属性

    • 使用render_kw属性

    • 在调用时加括号使用关键字参数的形式传入。如:form.username(style='width:20px;',class='bar')

4.2.3模板渲染表单

  1. 调用表单类的字段属性即可,同时也可以添加括号增加字段属性

    {{form.username}} / {{form.username(class='bar')}}

  2. Flask-WTF自动验证CSRF令牌,所以为了通过验证,需手动渲染这个字段。{{form.csrf_token}}

4.3.2验证表单数据

  1. 单纯使用WTForms,实例化表单类时要把request.form出入表单类,而Flask-WTF,不需要手动传入。注意:POST提交的表单,通过request.form获取数据,而GET提交的表单,通过request.args获取数据

  2. 验证表单

    • 首先实例化表单,再调用validate()方法验证表单。若对GET和POST请求执行不同代码,如GET渲染模板,POST调用validate()方法验证数据。即if reques.method =='POST' and form.validate():

    • form.validate_on_submit()合并了上面两个操作,但除了POST方法,PUT、PATCH、DELETE也会验证表单数据

    • form.data是匹配所有字段与对应数据的字典,一般使用form.字段属性名.data获取对应字段的数据列表

    • 对表单的请求使用PRG(Post/Redirect/Get)模式,即:对请求表单的POST请求返回重定向响应将最后一个请求转换为GET请求

4.3.3模板渲染错误消息

  1. form.errors匹配所有字段与对应错误消息的字典,一般使用form.字段属性名.errors获取对应字段的错误消息列表

  2. 像渲染flash()消息一样,可以使用for循环迭代错误消息列表

  3. 疑问:验证失败将错误消息添加到表单类实例的errors属性是自动进行的吗?不需手动传递?

4.4.2使用宏渲染表单

  1. 模板渲染需要重复做的工作:

    • 调用字段属性,获取<input>定义

    • 调用对应的label属性,获取<label>定义

    • 渲染错误消息

  1. macro.html的内容:

    {% macro form_field(field) %}
    {{ field.label }}<br>
    {{ field(**kwargs) }}<br>
    {% if field.errors %}
    {% for error in field.errors%}
    ...
    {% endfor%}
    {% endif %}
    {% endmacro %}
  1. 模板文件渲染的内容:

    {% from 'macro.html' import form_field %}

    <form method='POST'>
      {{ form.csrf_token }}
      {{ form_field(form.username) }}
    form>

4.4.3自定义验证器

  1. 行内验证器

    • 在表单类中定义以“validate_字段属性名”形式命名的方法,该方法接收两个位置参数,依次是form和field,前者是表单实例,后者是字段对象,field.data获取字段数据,这两个位置参数在验证表单时被调用传入。验证出错抛出ValidationError异常,传入错误信息做参数,如raise ValidationError('错了信息')

  1. 全局验证器

    • 实现工厂函数,即返回一个可调用的函数

      Flask Web第四章

4.4.4文件上传

  1. app.config['MAX_CONTENT_LENGTH']=1024*3 注意:默认单位为字节。app.config['UPLOAD_PATH']配置上传文件的目的文件夹

  2. 文件上传表单,需将表单的enctype属性设为“multipart/form-data”

  3. 手动处理时,request.files.get('photo')获取。当使用Flask—WTF时,会自动帮我们获取对应的文件对象,仍使用表单类属性的data属性获取,如:form.字段名.data

  4. 使用文件对象的save(‘文件保存路径'')方法保存文件。如:

    f=form.photo.data

    f.save('/uploads/photo.jpg')

  1. send_from_directory(),通过传入的文件路径返回相应的文件内容,类似Flask内置的static视图

  2. 多文件上传时,使用request.files。getlist('photo')获取所有上传文件对象的列表

4.4.6单表单多提交按钮

  1. 只有被单击的提交字段才会解析到request.form字典中。一般使用form.字段名.data,被单击的值是True,未被单击则是False

4.4.7单页面多表单

  1. 单视图处理

    • 一个页面多个表单时,要判断是哪个表单被提交。Flask-WTF根据请求方法判断表单是否提交,不判断是哪个表单被提交,需要手动判断。

    • 可以给两个表单的提交字段设置不同的name属性,使用form.字段名.data判断是否被提交

  2. 多视图处理

    • 使用不同视图函数对表单进行处理,两表单的提交字段的name可以使用相同名称,在视图函数中可继续form.validate_on_submit()方法验证

    • 疑问:Flask Web第四章

上一篇:lucene


下一篇:hash散列