当前位置:首页 » 《休闲阅读》 » 正文

Flask 与 Jinja2:构建动态 Web 应用指南(前)

4 人参与  2024年04月21日 16:56  分类 : 《休闲阅读》  评论

点击全文阅读


Flask简介:

Flask是一个用Python编写的小而强大的Web应用框架。它被设计为易于扩展的轻量级框架,正如其官网所说:“微型”不意味着您的整个Web应用必须放在单个Python文件中(虽然它确实可以),也不意味着Flask缺乏功能。相反,”微型“意味着Flask默认情况下保持核心简单但可扩展。

以下是Flask的一些关键特性:

开发服务器和调试器: Flask内置了一个开发服务器和一个交互式调试器。当您在开发模式下运行您的应用时,Flask会为您提供一个本地服务器,当您的代码更改时它会重新加载,并且当出错时提供一个有用的调试器。

集成单元测试支持: Flask支持单元测试,这意味着您可以使用Python的内置unittest库来编写测试,确保您的应用按预期工作。

RESTful请求分发: 使用Flask,您可以通过路由器将请求映射到Python函数上,这是创建RESTful应用的基础。

使用Jinja2模板引擎: Flask使用Jinja2模板引擎来动态构建前端。Jinja2是一个功能强大的模板引擎,它允许您在服务器端创建HTML模板,然后填入动态数据来呈现页面。

支持安全的Cookies(会话): Flask可以储存和操纵用户会话数据。它也处理Cookies和数据的安全性,比如通过签名来防止用户篡改Cookies中存储的数据。

Unicode基础: Flask 基于Unicode,使它处理国际化和本地化编码变得容易。

扩展性: Flask拥有一个被动的扩展框架,借助该框架第三方开发者能够很容易地为Flask添加新功能,比如ORM、表单验证、文件上传处理、各种开放式身份验证技术等。

WSGI 1.0兼容: Flask实现了WSGI协议,这是Python中应用于服务器和应用交互的标准接口。

基于Werkzeug和Jinja2: Flask 依赖于 Werkzeug WSGI工具集和Jinja2模板引擎,这些都是用Python编写的Pocco项目的一部分。

为什么学习Flask:

简单易学: Flask 有一个简单直观的 API,它允许开发者快速上手。即使是没有太多Web开发背景的人也能轻松理解基本概念并开始构建Web应用。

灵活性高: Flask 几乎不做任何假设关于您项目的怎样结构,这就给了您巨大的灵活性来组织您的应用如何执行任务。您可以选择自己的工具和库来完成任务,这是大型框架如 Django 那种 “全包” 方法所无法提供的。

微服务友好: Flask 的轻量级特性使其成为构建微服务架构的理想选择。每个服务可以是一个小型的 Flask 应用,独立地开发和部署,从而提升可伸缩性和维护性。

强大的扩展库: 虽然 Flask 本身很简单,但通过丰富的扩展库,开发者可以轻松地添加各种功能,包括用户认证、数据库集成、表单验证、上传管理等。

社区支持: Flask 有一个非常活跃的社区和较多的文档。如果遇到任何问题,通常都能在社区或者Stack Overflow上找到答案。

成熟稳定: Flask 自2004年推出以来,经过多年的开发,目前已经非常成熟和稳定,许多公司和项目依赖于它的生产。

快速开发: Flask 使搭建原型和迭代快速发生,你可以快速地从一个基础项目构建到一个完整功能的应用。

透明性: Flask的代码库相比其他框架来说比较简单,这使得其工作方式更加透明,也更容易理解其内部机制。

教育资源丰富: 存在大量针对 Flask 的教程、指南和实例项目,这为学习提供了极大的便利性。

适应不同规模的项目: 无论是小型的个人项目还是大型公司级应用,Flask 都可以胜任。

总的来说,Flask 提供了一个简单、灵活且功能强大的平台,使得Web开发变得既可控又高效。学习 Flask 能够让开发者在Web领域获得一项重要的技能,并且有助于构建可维护和可扩展的应用产品。

Jinja2在Flask中的作用:

模板渲染: Jinja2 允许您创建包含动态内容的 HTML 模板。在 Flask 中,您可以使用 Jinja2 渲染模板并将数据传递给模板,然后生成最终的 HTML 页面。这使得开发 Web 应用程序变得更加灵活和易于维护。

模板继承: Jinja2 支持模板继承,这是一种重用模板代码并在不同页面中共享相同布局的强大技术。通过使用模板继承,您可以在 Flask 中创建具有一致性布局的网站,并更轻松地对布局进行更改和更新。

模板变量: Jinja2 允许您在模板中使用变量来动态显示数据。在 Flask 中,您可以在视图函数中将数据传递给模板,并在模板中使用这些数据来呈现页面内容。

模板控制结构: Jinja2 支持丰富的控制结构,如条件语句、循环语句和过滤器等。这些控制结构使您能够在模板中进行逻辑判断和数据处理,从而实现更复杂的页面逻辑。

安全过滤: Jinja2 提供了安全过滤器和自动转义功能,可以帮助您防止跨站脚本(XSS)等安全问题。这使得在 Flask 中开发安全的 Web 应用程序变得更加容易。

第一部分:Flask 概述

一. Flask的基础知识和特点:

微框架: Flask 被称为微框架,主要是因为它的核心非常简单,但功能可以通过插件无限扩展。

WSGI 兼容: Flask 实现了 WSGI (Web Server Gateway Interface) 服务器与应用程序接口的规范,允许它与多种实现该协议的服务器配合工作。

路由系统: Flask 提供了一个强大的 URL 路由系统,可以使用装饰器在视图函数上建立路由,方便定义 URL 规则。

模板引擎: Flask 使用 Jinja2 作为模板引擎,它支持条件语句、循环、过滤器、宏等高级功能,帮助在服务器端生成动态 HTML 内容。

集成开发服务器和调试器: Flask 自带了一个开发服务器,以及一个交互式的调试器。这意味着,在开发过程中,如果代码出现错误,可以在浏览器中直接交互地追踪问题。

单元测试支持: Flask 支持扩展单元测试以确保应用的稳定性,它允许为应用编写和运行测试用例,确保代码质量。

请求分发: Flask 可以处理 Web 请求并作出响应,允许开发者编写视图函数来响应不同的 HTTP 请求。

插件和扩展: 虽然 Flask 本身很“小”,但它支持使用扩展来添加新功能,如 ORM、表单验证、用户认证等,这加强了其适应不同项目需求的能力。

轻量和灵活: Flask 本身代码量小,不强制要求项目布局或是依赖,这赋予开发者高度的灵活性,可以按项目的具体需求来选择工具和库。

易于理解和上手: Flask 的简单性还体现在其代码的可阅读性以及文档的完备性上,使得其非常适合初学者学习和使用。

二. Flask 适用于哪些类型的项目:

小型项目和原型开发: Flask 的简洁性和灵活性使其非常适合用于小型项目和原型开发。如果您需要快速地构建一个简单的 Web 应用程序或原型来验证概念,Flask 是一个不错的选择。

API 服务: Flask 可以作为构建 RESTful API 服务的工具。它支持路由、请求处理、数据序列化等功能,使得开发 API 变得简单和高效。

微服务架构: Flask 在微服务架构中也表现出色。您可以使用 Flask 快速构建独立的微服务,并通过 HTTP 或其他协议进行通信,从而实现系统的分布式和模块化。

学习和教学: 由于 Flask 的简单性和易学性,它常被用于学习 Python Web 开发和教学。对于初学者来说,使用 Flask 可以快速上手,并且能够了解 Web 开发的基本概念和技术。

Web 应用程序的快速原型和开发: 对于需要快速原型开发或者对时间敏感的项目,Flask 是一个理想的选择。它不需要大量的配置和学习成本,可以让开发者快速构建出具有基本功能的 Web 应用程序。

自定义和定制性强的项目: Flask 的设计理念是简单而灵活,它提供了很多自定义和扩展的接口,使得开发者可以根据项目需求进行灵活的定制和扩展。

虽然 Flask 适用于许多类型的项目,但对于大型、复杂的企业级应用程序,可能需要考虑使用更完整、功能更丰富的框架,如 Django。Flask 更适合于小规模、中小型的项目以及快速开发和原型验证。

三.Flask 的优势和局限性

优势:

轻量级和简单易学: Flask 的设计理念是简单和轻量级,没有过多的依赖和复杂性,因此易于学习和上手。

灵活性: Flask 提供了很高的灵活性,您可以根据项目需求自由选择和组合需要的功能,不受框架限制。

模块化: Flask 支持模块化开发,可以轻松地将应用程序拆分为不同的模块或者添加额外的功能模块。

集成度高: Flask 可以与其他 Python 库和工具很好地集成,如 SQLAlchemy、WTForms、Jinja2 等,使得开发更加便利。

RESTful API 支持: Flask 提供了很好的支持来构建 RESTful API 服务,可以快速开发和部署 API 接口。

社区活跃: Flask 拥有一个活跃的社区,有大量的插件和扩展可供选择,可以帮助开发者加速开发过程。

局限性:

过于简洁: 有时候,Flask 的简洁和灵活性也可能成为一种限制,对于大型、复杂的应用程序可能需要自行添加一些功能或者扩展,增加开发成本和工作量。

缺少内置功能: 相比于其他 Web 框架如 Django,Flask 在一些方面缺少内置功能,需要依赖第三方插件或者自行实现。

自由度带来的责任: Flask 的灵活性也意味着开发者需要自行做出许多决策,包括项目结构、安全性、数据库选型等,这可能增加了开发者的责任和工作量。

不适合大规模项目: 尽管 Flask 可以用于大型项目,但对于复杂度较高、团队规模较大的企业级项目,可能需要更完整和功能更丰富的框架来满足需求。

第二部分:设置开发环境

四.环境搭建以及新手入门

创建虚拟环境(可选): 首先,您可以选择在 Anaconda 中创建一个新的虚拟环境来安装 Flask,以隔离不同项目的依赖。可以使用以下命令创建虚拟环境,其中 myenv 是环境名称,您可以自行替换为喜欢的名称。
conda create -n myenv python=3.8.15
激活虚拟环境: 激活刚刚创建的虚拟环境,命令如下:
conda activate myenv
安装 Flask: 在虚拟环境中,使用 pip 命令安装 Flask 和相关依赖:
pip install flask
安装其他依赖(可选): 如果您的项目需要其他依赖,比如数据库驱动、表单处理等,可以继续使用 pip 安装相应的依赖包,例如:
pip install flask_sqlalchemy flask_wtf

上述命令安装了 Flask SQLAlchemy(用于数据库操作)和 Flask WTF(用于表单处理)等常用扩展。

验证安装: 安装完成后,可以验证 Flask 是否安装成功。创建一个简单的 Python 脚本,例如 app.py,并编写一个最基本的 Flask 应用程序:
from flask import Flaskapp = Flask(__name__)@app.route('/')def hello_world():    return 'Hello, Flask!'if __name__ == '__main__':    app.run(debug=True)
运行应用程序: 在命令行中切换到保存了 app.py 的目录,并执行以下命令来运行应用程序:
python app.py

应用程序将会运行在本地服务器上,并在终端显示类似于 Running on http://127.0.0.1:5000/ 的信息。打开浏览器并访问该地址,您应该能够看到 "Hello, Flask!" 的消息。

第三部分:理解 Flask 的路由

五. Flask路由

Flask 的路由系统使得 Web 应用可以响应特定的 URL,每个路由映射到一个 Python 函数。定义路由的方式很直接,一般通过应用实例上的 route() 装饰器和相应的视图函数来完成。

# 首先,需要从 flask 模块导入 Flask 类来创建应用实例from flask import Flask# 创建 Flask 应用实例。Flask 类的实例将会是我们的 WSGI 应用app = Flask(__name__)# 使用 app.route 装饰器定义基本路由。# 当客户端访问网站根目录即 / 时,会调用这个视图函数@app.route('/')def index():    return 'Welcome to my Flask app!'# Flask 能够通过在 URL 中包含特定的变量部分来支持变量规则。# 使用尖括号(<variable_name>)标记动态部分,它将作为关键字参数传递给与规则相关联的函数@app.route('/hello/<name>')def hello(name):    # 在这个视图函数中,可以使用变量 name 来响应 URL    return f'Hello, {name}!'# 可以创建带有多个动态部分的 URL 规则,并以不同类型转换变量值@app.route('/post/<int:post_id>')def show_post(post_id):    # post_id 的类型会自动地由 string 转换成 int    return f'Post ID is {post_id}'# 可以为一个视图函数绑定多个 URL,这样可以提供多种不同的路径映射到同一页面@app.route('/about')@app.route('/about-us')def about():    return 'This is the about page.'# 最后,需要检查是直接运行此脚本还是通过其他方式调用的脚本。# 如果是直接运行,则启动 Flask 的开发服务器if __name__ == '__main__':    app.run(debug=True)  # 启用调试模式,服务器会在代码修改后自动重启,并在发生错误时提供调试信息

以上代码展示了 Flask 的基础路由定义:

使用 @app.route() 装饰器来告知 Flask 哪个 URL 应当触发我们的函数。

动态地从 URL 中捕获值。

可以为变量部分指定一个可选的转换器来指定它的类型。

一个视图函数可以绑定到多个路由。

六. URL 构建函数

在 Flask 中,URL 构建函数是一个非常有用的工具,用于构建动态生成的 URL。它可以帮助您在视图函数中动态生成 URL,而不必硬编码 URL 地址,这样可以提高代码的可维护性和灵活性。Flask 提供了 url_for() 函数来进行 URL 构建。

1. url_for() 函数的基本用法:

from flask import Flask, url_forapp = Flask(__name__)@app.route('/')def index():    # 使用 url_for() 构建路由    user_profile_url = url_for('show_user_profile', username='john')    return f'The URL for user profile is: {user_profile_url}'@app.route('/user/<username>')def show_user_profile(username):    return f'User: {username}'if __name__ == '__main__':    app.run(debug=True)

在上述示例中,url_for() 函数用于构建名为 show_user_profile 的视图函数的 URL。在 index() 视图函数中,调用 url_for('show_user_profile', username='john') 将生成动态 URL /user/john,然后将该 URL 返回给用户。

2. 构建静态资源 URL:

url_for() 函数不仅可以构建动态路由的 URL,还可以用于构建静态资源的 URL,如 CSS 文件、JavaScript 文件或者图片等。示例如下:

from flask import Flask, url_forapp = Flask(__name__)@app.route('/')def index():    # 使用 url_for() 构建静态资源的 URL    css_url = url_for('static', filename='styles.css')    js_url = url_for('static', filename='scripts.js')    return f'The CSS URL is: {css_url}<br>The JavaScript URL is: {js_url}'if __name__ == '__main__':    app.run(debug=True)

在这个示例中,url_for('static', filename='styles.css')url_for('static', filename='scripts.js') 分别构建了静态 CSS 和 JavaScript 文件的 URL,这些文件位于 Flask 应用程序的 static 目录下。

3. 参数和默认值:

url_for() 函数的第一个参数是视图函数的名称,后面可以跟着动态路由参数,例如 username='john'。如果视图函数接受多个参数,可以依次列出。另外,您也可以在路由中定义默认值,这样在构建 URL 时如果没有传入参数,将使用默认值。

第四部分:模板与 Jinja2 介绍

七. Jinja2与Flask的关系

Jinja2 是一个功能强大的模板引擎,主要用于生成动态内容的 HTML 页面。它与 Flask 之间有着密切的关系,因为 Flask 默认使用 Jinja2 作为模板引擎来渲染页面。

1. Jinja2 的特点和功能:

模板继承: Jinja2 支持模板继承,使得可以定义一个基础模板,并在其他模板中继承和扩展这个基础模板,实现页面布局的复用和共享。

模板变量: 可以在模板中使用变量来动态显示数据,例如从 Flask 视图函数传递的数据可以在模板中渲染。

控制结构: 支持条件语句、循环语句等控制结构,使得可以在模板中进行逻辑判断和数据处理。

过滤器: 提供了丰富的过滤器,可以对数据进行格式化、处理和过滤,例如日期格式化、字符串处理等。

安全性: 自带自动转义功能,可以防止跨站点脚本(XSS)攻击,提高页面安全性。

2. Flask 中的 Jinja2:

Flask 使用 Jinja2 作为默认的模板引擎,这意味着在 Flask 中开发 Web 应用程序时,您可以直接使用 Jinja2 来渲染模板并生成 HTML 页面。Flask 提供了与 Jinja2 集成的功能,使得在 Flask 视图函数中渲染模板变得非常简单。

3. Flask 中使用 Jinja2:

在 Flask 中使用 Jinja2 主要涉及两个方面:

模板文件: 在 Flask 项目的 templates 目录中编写 Jinja2 模板文件,这些模板文件通常使用 .html.jinja2 扩展名。

视图函数: 在 Flask 的视图函数中使用 render_template() 函数来渲染模板并将数据传递给模板,例如:

from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')def index():    username = 'John Doe'    return render_template('index.html', username=username)

在上述示例中,render_template() 函数用于渲染名为 index.html 的模板,并传递 username 变量给模板,模板可以使用这个变量来生成动态内容。

八. Jinja2的基本语法(变量、控制结构、继承、过滤器)

1. 变量:

Jinja2 中的变量用 {{ 变量名 }} 来表示,可以在模板中使用变量来动态显示数据。例如:

<p>Hello, {{ name }}</p>
# Flask中将变量传递给模板from flask import Flask, render_templateapp = Flask(__name__)# 也可指定模板目录# app = Flask(__name__, template_folder="/opt/python-projects/flask")@app.route('/')def hello():    name = "MichaelxcT"    return render_template('hello.html', name=name)if __name__ == '__main__':    app.run(host='0.0.0.0', port=8000, debug=True)

在上面的示例中,{{ name }} 是一个变量,它将根据传递给模板的值来动态渲染。

2. 控制结构:

Jinja2 提供了丰富的控制结构,包括条件语句、循环语句等,用于在模板中进行逻辑判断和数据处理。以下是一些常见的控制结构:

条件语句: 使用 {% if 条件 %}...{% endif %} 来实现条件判断,例如:
<!-- if.html模板 --><!DOCTYPE html><html><head>    <title>Hello</title></head><body>    {% if user %}        {% if user.age >= 18 %}            <h1>Hello {{ user.name }}, you are an adult!</h1>        {% else %}            <h1>Hello {{ user.name }}, you are a minor!</h1>        {% endif %}    {% else %}        <h1>Hello, anonymous user!</h1>    {% endif %}</body></html>
# if.py# Flask中使用if控制结构from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')def hello():    user = {"name": "MichaelxcT", "age": 22}    return render_template('if.html', user=user)if __name__ == '__main__':    app.run(host='0.0.0.0', port=8000, debug=True)

在上面的示例中,使用if语句来控制输出,根据用户的年龄显示不同的消息。

循环语句: 使用 {% for 变量 in 列表 %}...{% endfor %} 来实现循环,例如:
<!-- for.html模板 --><!DOCTYPE html><html><head>    <title>Hello</title></head><body>    {% for user in users %}        <h1>Hello {{ user.name }}!</h1>        <p>You are {{ user.age }} years old.</p>    {% endfor %}</body></html>
# for.py# Flask中使用for循环结构from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')def hello():    users = [{"name": "MichaelxcT", "age": 22}, {"name": "zhangsan", "age": 30}]    return render_template('for.html', users=users)if __name__ == '__main__':    app.run(host='0.0.0.0', port=8000, debug=True)

在上面的示例中,使用 for 循环来遍历用户列表,并输出每个用户的信息。

3. 继承:

Jinja2 支持模板继承,可以定义一个基础模板,并在其他模板中继承和扩展这个基础模板。使用 {% extends 'base.html' %} 来继承模板,使用 {% block %}...{% endblock %} 来定义块并覆盖基础模板中的内容。例如:

基础模板 base.html

<!DOCTYPE html><html><head>    <title>{% block title %}My Website{% endblock %}</title></head><body>    {% block content %}{% endblock %}</body></html>

继承基础模板并扩展内容的子模板:

<!-- base.html模板 --><!DOCTYPE html><html><head>    <title>{% block title %}{% endblock %}</title></head><body>    {% block content %}{% endblock %}</body></html>
<!-- extend.html模板 -->{% extends "base.html" %}{% block title %}Hello{% endblock %}{% block content %}    <h1>Hello World!</h1>{% endblock %}
# extend.py# Flask中使用继承from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')def hello():    return render_template('extend.html')if __name__ == '__main__':    app.run(host='0.0.0.0', port=8000, debug=True)

在上面的示例中,定义了一个名为 base.html 的模板,并在 extend.html 模板中继承了该模板。extend.html 模板中可以重写 base.html 模板中的块,并在其中添加新的内容。

4.过滤器:

过滤器在 Jinja2 中用于对变量内容进行转换和格式化。过滤器通过管道符号(|)应用到变量上,可以单独使用或串联使用,允许你对输出进行链式转换。以下是一些内置过滤器的例子及自定义过滤器的编写方法。

常用的内置过滤器:

safe:禁用自动的字符串转义。

capitalize:把字符串的首字母转换为大写,其余字母转换为小写。

lower:把字符串转换为小写。

upper:把字符串转换为大写。

title:把字符串中的每个单词的首字母转换为大写。

trim:去除字符串首尾的空白字符。

striptags:删除字符串中所有 HTML 标签。

urlencode:将字符串进行 URL 编码。

jsonify:过滤器将变量内容转换为 JSON 格式的字符串。

first:获取列表的第一个元素。

last:获取列表的最后一个元素。

length:获取字符串或列表的长度。

default:如果一个变量未定义或为假(false),设置一个默认值。

示例:

{{ '<some_html>' | safe }}{{ 'JOHN DOE' | lower }}{{ [1, 2, 3, 4] | last }}

第五部分:使用 Jinja2 的高级特性

九. 宏、包含、测试、以及自定义过滤器等高级用法

1. 宏(Macros):

在 Jinja2 中,宏类似于 Python 的函数。你可以定义一块可重用的代码,并可以在模板中多次调用它。

{% macro render_comment(comment) %}  <div class="comment">    <h2>{{ comment.author }}</h2>    <p>{{ comment.content }}</p>  </div>{% endmacro %}

你可以像这样在其他地方调用它:

{{ render_comment(comment) }}

2. 包含(Include):

include 语句允许你将一个模板中的内容包含进另一个模板。这有助于重用模板片段和组织代码。

<div>  <h1>Welcome to my blog</h1>  {% include 'includes/navigation.html' %}</div>

3. 测试(Tests):

Jinja2 中的测试用来检测变量的属性。例如,你可以检查一个变量是否是字符串、是否定义了等。

{% if comment is not none %}  <p>Comment: {{ comment }}</p>{% endif %}

4. 自定义过滤器(Custom Filters):

Jinja2 允许你定义自己的过滤器。过滤器是当你需要执行变量转换时使用的函数。

要创建一个自定义过滤器,你需要先定义一个 Python 函数,然后通过app.template_filter()注册为过滤器。

@app.template_filter('capitalize')def capitalize_filter(s):    return s.capitalize()

在模板中使用这个过滤器:

<p>{{ "hello world" | capitalize }}</p>

这会输出 "Hello world"。

6. 综合示例:

from flask import Flask, render_templateapp = Flask(__name__)@app.template_filter('capitalize')def capitalize_filter(s):    return s.capitalize()@app.route('/')def index():    comments = [        {'author': 'Alice', 'content': 'A great day!'},        {'author': 'Bob', 'content': 'Interesting post...'}    ]    return render_template('index.html', comments=comments)# 定义宏在模板文件中,例如 macros.html

macros.html 文件:

{% macro render_comment(comment) %}  <div class="comment">    <h2>{{ comment.author | capitalize }}</h2>    <p>{{ comment.content }}</p>  </div>{% endmacro %}

index.html 文件:

{% from 'macros.html' import render_comment %}<html><body>  {% include 'includes/navigation.html' %}  <h1>Comments</h1>  {% for comment in comments %}    {{ render_comment(comment) }}  {% endfor %}</body></html>

第六部分:表单与用户输入

介绍 Flask 中处理表单输入的方法。

十. Flask 中处理表单输入的方法

在 Flask 中处理表单输入是通过 WTForms 或 Flask 自身的请求对象来进行的,这里将重点介绍如何使用 Flask 的 request 对象来处理表单输入。

1. Flask request 对象:

Flask 的 request 对象包含了来自客户端的所有请求数据。为了处理表单数据,你通常会从 request.form 属性中提取数据,它是一个类字典对象,包含了表单的键值对:

from flask import Flask, request, render_templateapp = Flask(__name__)@app.route('/form', methods=['GET', 'POST'])def form():    if request.method == 'POST':        # 提取表单数据        username = request.form.get('username')        email = request.form.get('email')        password = request.form.get('password')        # 处理表单数据        # ...(例如验证、存储至数据库等)        # 返回响应或重定向        return 'Form Submitted!'    # 如果请求方法是 GET,展示表单页面    return render_template('form.html')

form.html 模板中,你需要创建一个 HTML 表单指向 /form 路由并以 POST 方法提交,例子如下:

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Form Example</title></head><body>    <form action="/form" method="post">        <label for="username">Username:</label>        <input type="text" id="username" name="username">        <label for="email">Email:</label>        <input type="email" id="email" name="email">        <label for="password">Password:</label>        <input type="password" id="password" name="password">        <input type="submit" value="Submit">    </form></body></html>

在上述示例中:

使用 @app.route 装饰器将函数 form() 绑定到路由 /form 上,允许 GETPOST 两种 HTTP 方法。

若 HTTP 请求为 POST(表单提交后),从 request.form 中提取表单数据。

使用 request.form.get('input_name') 方法,安全地获取表单输入值,如果输入框未填写,则返回 None

在 Flask 中处理表单输入通常涉及以下步骤:

创建一个 HTML 表单用于接收用户输入。

在 Flask 应用中定义一个视图函数来处理表单提交的路由。

使用 Flask 的 request 对象处理提交的表单数据。

下面是一个简单的 Flask 脚本,展示了如何通过 POST 请求处理表单数据,并在提交后向用户反馈信息:

import flaskfrom flask import Flask, render_template, requestapp = Flask(__name__)@app.route('/submit', methods=['GET', 'POST'])def submit():    if request.method == 'POST':        # 假设提交的表单有“name”和“age”字段        name = request.form['name']        age = request.form['age']        # 处理表单数据(如保存到数据库等)        # 在实际应用中,你还需要进行数据的验证和清洗        return '表单提交成功!你的名字是 {} 年龄是 {}'.format(name, age)    else:        # 在 GET 请求下,渲染一个空的表单页面        return render_template('submit_form.html')if __name__ == '__main__':    app.run(debug=True)

在该例子中,我们首先为路由 /submit 定义了一个视图函数 submit。然后,根据 HTTP 请求的方法(GET 或 POST),执行不同的操作:

如果请求是 POST(这意味着用户提交了表单),我们从 request.form 字典中提取出用户通过表单输入的 nameage 字段,并返回一条确认信息。

如果请求是 GET(用户通过浏览器访问该页面),那么我们渲染并返回一个 HTML 表单,允许用户输入数据。

对应的 HTML 表单模板 submit_form.html 可能是这样的:

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Submit Form</title></head><body>    <form action="/submit" method="post">        <label for="name">姓名:</label>        <input type="text" id="name" name="name">        <label for="age">年龄:</label>        <input type="text" id="age" name="age">        <input type="submit" value="提交">    </form></body></html>

在这个表单中,我们有两个输入框和一个提交按钮。提交按钮会将表单数据以 POST 请求的方式发送到 /submit 路由。然后 Flask 应用中的 submit 视图函数会处理这些输入数据。

除了使用 request.form.get('input_name') 方法获取表单输入值,还有以下方式可用:

2. 使用索引直接访问:

这是获取表单输入值的最直接方式。你可以像访问字典一样,通过索引直接获取对应的值:

name = request.form['name']

请注意,如果表单中没有 'name' 字段,这种方式会引发一个 KeyError。因此,除非你确定 'name' 字段一定存在,否则使用这种方式获取表单输入值可能并不安全。

3. 使用 request.form.getlist 方法:

如果你的 HTML 表单包含有多个具有相同名字的输入框(例如复选框组),那么你可能需要使用 request.form.getlist('input_name') 方法来获取所有选中的值:

selected_options = request.form.getlist('options')

此时 selected_options 会是一个列表,包含所有选中选项的值。

十一. WTForms 和如何简化表单处理

WTForms 是一个方便我们处理 Flask 网页表单的 Python 库。通过 WTForms,我们可以轻松定义表单类和验证规则,自动处理请求中表单字段的绑定,提升代码的效率和可读性。

1. 安装WTForms:

pip install wtforms

2. 在 Flask 中使用 WTForms:

2.1 定义表单类和字段

WTForms 让我们可以用类的形式定义表单,每个类的字段都可以是一个表单字段。举例来说,如果我们要创建一个包含 emailpassword 的登录表单,可以这样编写:

from flask_wtf import FlaskFormfrom wtforms import StringField, PasswordFieldfrom wtforms.validators import DataRequired, Emailclass LoginForm(FlaskForm):    email = StringField('Email', validators=[DataRequired(), Email()])    password = PasswordField('Password', validators=[DataRequired()])

这里,LoginForm 类就表示一个表单,emailpassword 字段分别代表两个表单输入框。我们还添加了 DataRequiredEmail 验证器,要求这两个字段不能为空,且 email 字段的值必须符合电子邮件格式。

2.2 在视图函数中使用表单

在视图函数中,我们可以生成表单实例并将其传递给模板。模板可以使用这个表单实例生成 HTML 表单:

from flask import render_template, requestfrom .forms import LoginForm@app.route('/login', methods=['GET', 'POST'])def login():    form = LoginForm()    if form.validate_on_submit():        email = form.email.data        password = form.password.data        # 这里可以添加处理表单数据的代码(如检查用户身份)        return 'Logged in successfully.'    return render_template('login.html', form=form)

这里,form.validate_on_submit() 方法会在表单提交时进行字段验证,如果验证全部通过,方法会返回 True

2.3 在模板中渲染表单

在模板中,我们可以很方便地渲染出表单的 HTML 代码:

<form method="POST">    {{ form.hidden_tag() }}    <p>        {{ form.email.label }}<br>        {{ form.email(size=20) }}<br>        {% for error in form.email.errors %}            <span style="color: red;">[{{ error }}]</span>        {% endfor %}    </p>    <p>        {{ form.password.label }}<br>        {{ form.password(size=20) }}<br>        {% for error in form.password.errors %}            <span style="color: red;">[{{ error }}]</span>        {% endfor %}    </p>    <p><input type="submit"

点击全文阅读


本文链接:http://zhangshiyu.com/post/98437.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1