表单提交

Posted liangliangzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了表单提交相关的知识,希望对你有一定的参考价值。

# 表单提交

### flask-bootstrap

- 说明:在flask中如何使用bootstrap,可以通过此扩展进行解决。

- 安装:`pip install flask-bootstrap`

- 使用:

  ```python
  from flask_bootstrap import Bootstrap

  bootstrap = Bootstrap(app)
  ```

- 模板:

  ```html
  {# 继承自bootstrap的基础模板 #}
  {% extends bootstrap/base.html %}

  {% block title %}标题{% endblock %}

  {% block content %}
      <div class="container">
      内容
      </div>
  {% endblock %}
  ```

- bootstrap基础模板中的block

  | block   | 说明                 |
  | ------- | ------------------ |
  | doc     | 整个HTML文档           |
  | html    | 整个html标签           |
  | head    | 整个head标签           |
  | title   | 整个title标签          |
  | metas   | 一组meta标签           |
  | styles  | 一组link标签(加载CSS文件)  |
  | body    | 整个body标签           |
  | navbar  | 导航条                |
  | content | 网页内容               |
  | scripts | 一组script标签(加载JS文件) |

  > 提示:当重写一个block后,发现原来的显示全没了,很可能是因为没有使用{{ super() }}。

### 项目基础模板定制

- 从bootstrap官网复制一个顺眼的导航条
- 将`container-fluid`改为`container`
- 改为反色导航条,将`navbar-default`改为`navbar-inverse`
- 设置为直角:`style="border-radius: 0px;"`
- 根据需要定制导航条上的显示内容

### 加载静态资源

- flask中静态资源默认存放在static目录下,因此目录结构如下:

  ```
  project/
      manage.py            # 启动控制文件
      templates/            # 模板文件目录
      static/                # 静态资源目录
          img/
          css/
          js/
          favicon.ico
  ```

- 加载静态资源

  ```html
  {# 基础模板中,加载网站收藏夹小图标 #}
  {% block head %}
      {{ super() }}
      <link rel="icon" type="image/x-icon" href="{{ url_for(‘static‘, filename=‘favicon.ico‘) }}" />
  {% endblock %}

  {# 加载图片资源 #}
  <img src="{{ url_for(‘static‘, filename=‘img/gyy.jpg‘) }}" />

  {#  加载CSS文件 #}
  {% block styles %}
      {{ super() }}
      <link type="text/css" href="{{ url_for(‘static‘, filename=‘css/common.css‘) }}" rel="stylesheet" />
  {% endblock %}

  {# 加载JS文件 #}
  {% block scripts %}
      {{ super() }}
      <script type="text/javascript" src="{{ url_for(‘static‘, filename=‘js/common.js‘) }}"></script>
  {% endblock %}
  ```

### 原生表单

- 准备模板文件`login.html`:

  ```html
  <form method="post" action="/check/">
      用户名:<input name="username" /><br />
      <input type="submit" />
  </form>
  ```

- 添加视图函数,并渲染模板文件:

  ```python
  @app.route(/login/)
  def login():
      return render_template(login.html)
  ```

- 添加检验视图函数:

  ```python
  @app.route(/check/, methods=[POST])
  def check():
      return 登录成功
  ```

- 一个路由接收两种请求:

  ```python
  @app.route(/login/, methods=[GET, POST])
  def login():
      if request.method == GET:
          return render_template(login.html)
      else:
          # request.form存放了所有的POST请求数据
          # return request.form.get(username)
          # request.values存放了所有GET/POST请求数据
          return request.values.get(username)
  ```

### flask-wtf

- 说明:表单处理的扩展库,提供了CSRF、字段校验等功能,使用非常方便

- 安装:`pip install flask-wtf`

- 使用:

  - 创建表单类

  ```python
  # 导入表单基类
  from flask_wtf import FlaskForm
  # 导入相关字段
  from wtforms import StringField, SubmitField
  # 导入相关验证器
  from wtforms.validators import Length

  # 创建表单类
  class NameForm(FlaskForm):
      name = StringField(用户名, validators=[Length(3, 10, message=用户名长度必须在3~10个字符之间)])
        submit = SubmitField(提交)
  ```

  - 添加视图函数,创建表单对象,并渲染模板文件:

  ```python
  @app.route(/, methods=[GET, POST])
  def index():
      # 创建表单对象
      form = NameForm()
      # 判断是否是有效的提交
      if form.validate_on_submit():
          # 提取表单数据
          return form.name.data
      return render_template(form.html, form=form)
  ```
    - 原生渲染表单

  ```html
  <form method="post">
        {# CSRF字段 #}
        {{ form.hidden_tag() }}
        {{ form.name.label() }}{{ form.name(id=xxx, class=yyy) }}
        {% for e in form.name.errors %}
            <div>{{ e }}</div>
        {% endfor %}
        {{ form.submit() }}
  </form>
  ```
    - 使用bootstrap方式进行快速渲染

  ```html
  {# 继承自bootstrap基础模板 #}
  {% extends bootstrap/base.html %}

  {# 导入快速渲染的宏 #}
  {% from bootstrap/wtf.html import quick_form %}

  {% block content %}
      <div class="container">
          {# 在合适位置快速渲染表单 #}
          {{ quick_form(form) }}
      </div>
  {% endblock %}
  ```


- POST重定向到GET:因为浏览器会记录最后的请求状态,点击刷新时POST请求会有问题。

  ```python
  @app.route(/, methods=[GET, POST])
  def index():
      # 创建表单对象
      form = NameForm()
      # 判断是否是有效的提交
      if form.validate_on_submit():
          # 提取表单数据
          session[name] = form.name.data
          return redirect(url_for(index))
      name = session.get(name)
      return render_template(form2.html, form=form, name=name)
  ```

- 常见字段类型

  | 字段类型          | 说明                  |
  | ------------- | ------------------- |
  | StringField   | 普通文本字段              |
  | Submit        | 提交按钮                |
  | PasswordField | 密文字段                |
  | HiddenField   | 隐藏字段                |
  | RadioField    | 单选框                 |
  | BooleanField  | 复选框                 |
  | FileField     | 文件上传                |
  | SelectField   | 下拉框                 |
  | TextAreaField | 文本域                 |
  | IntegerField  | 文本字段,值为整数           |
  | FloatField    | 文本字段,值为浮点数          |
  | DateField     | datetime.date类型     |
  | DateTimeField | datetime.datetime类型 |

- 常见验证器

  | 验证器          | 说明                  |
  | ------------ | ------------------- |
  | Length       | 规定字符长度              |
  | DataRequired | 确保字段有值(提示信息与所写的不一致) |
  | Email        | 邮箱地址                |
  | IPAddress    | IP地址                |
  | NumberRange  | 数值的范围               |
  | URL          | 统一资源定位符             |
  | EqualTo      | 验证两个字段的一致性          |
  | Regexp       | 正则验证                |

  - 自定义验证函数

  ```python
  from wtforms.validators import ValidationError

  class NameForm(FlaskForm):
      。。。
      def validate_name(self, field):
          if len(field.data) < 6:
              raise ValidationError(用户名不能少于6个字符)
  ```

  > 总结:写字段验证函数,就是写一个validate_字段名的函数

### 消息闪烁

- 说明:

  当用户发出请求后,状态发生了改变,需要系统给出警告、提示等信息时,通常是弹出一条消息,指示用户下一步的操作,用户可以手动关闭提示消息。而且整个的过程不会影响页面原有的显示。

- 使用:

  - 在需要弹出消息时,使用`flash`函数保存闪烁消息

  ```python
  @app.route(/, methods=[GET, POST])
  def index():
      # 创建表单对象
      form = NameForm()
      # 判断是否是有效的提交
      if form.validate_on_submit():
          last_name = session.get(name)
          if last_name and form.name.data != last_name:
              flash(大哥,又换签名了!)
          # 提取表单数据
          session[name] = form.name.data
          return redirect(url_for(index))
      name = session.get(name)
      return render_template(form2.html, form=form, name=name)
  ```

  - 在模板文件中显示闪烁消息时,可以通过函数`get_flashed_messages`获取
  - 从bootstrap上粘贴一个可消失的警告框

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

### flask-moment

- 说明:专门负责时间本地化显示的扩展库,使用非常方便

- 安装:`pip install flask-moment`

- 使用:

  - python代码

  ```python
  from flask_moment import Moment

  moment = Moment(app)

  @app.route(/mom/)
  def mom():
      from datetime import datetime, timedelta
      current_time = datetime.utcnow() + timedelta(seconds=-60)
      return render_template(mom.html, current_time=current_time)
  ```

  - 模板文件

  ```html
  {# 加载jQuery #}
  {{ moment.include_jquery() }}

  {# 加载moment.js #}
  {{ moment.include_moment() }}

  {# 设置语言 #}
  {{ moment.locale(zh-CN) }}

  {# 简单的格式化时间显示 #}
  <div>时间:{{ moment(current_time).format(LLLL) }}</div>
  <div>时间:{{ moment(current_time).format(LLL) }}</div>
  <div>时间:{{ moment(current_time).format(LL) }}</div>
  <div>时间:{{ moment(current_time).format(L) }}</div>

  {# 自定义格式化显示 #}
  <div>自定义:{{ moment(current_time).format(YYYY-MM-DD HH:mm:ss) }}</div>

  {# 显示时间差 #}
  <div>发表于:{{ moment(current_time).fromNow() }}</div>
  ```

### 练习:

- 完成用户的注册登录功能

 

以上是关于表单提交的主要内容,如果未能解决你的问题,请参考以下文章

Form标签表单回显与提交

提交到 ASP.NET 页面的 PDF 表单创建返回 HTML 文件

带有固定按钮的片段

HTML 表单提交 的简单代码

在 Google 跟踪代码管理器中,触发器类型“表单提交”适用于 Google 表单提交吗?

php过滤表单提交的html等危险代码