Python Flask 入门介绍 – wiki基地


Python Flask 入门介绍:从零构建你的第一个Web应用

欢迎来到激动人心的Web开发世界!如果你已经掌握了一些 Python 基础知识,并渴望构建自己的网站或Web服务,那么 Flask 是一个绝佳的起点。它是一个轻量级的 Python Web 框架,以其简洁、灵活和易于上手而闻名。

本文将带你从零开始认识 Flask,一步步构建你的第一个Web应用,并深入探讨其核心概念。无论你是想构建一个简单的博客、API服务,还是一个小型Web应用,Flask 都能帮你快速实现想法。

准备好了吗?让我们开始 Flask 的探索之旅!

1. 什么是 Flask?为什么选择它?

Flask 是一个微框架 (Microframework)。 这里的“微”不是指功能少,而是指它核心简洁、依赖较少、不强制你使用特定的工具或技术。它只提供了构建Web应用最基本的功能:请求处理、路由、模板渲染等。

为什么选择 Flask?

  1. 简单易学: Flask 的API设计直观,代码量少,非常适合新手入门。
  2. 灵活自由: Flask 不做过多限制,你可以自由选择数据库、模板引擎(虽然默认推荐 Jinja2)、ORM (Object-Relational Mapper) 等组件。这给了开发者极大的灵活性,可以根据项目需求定制技术栈。
  3. 扩展丰富: 尽管核心小巧,Flask 拥有一个庞大而活跃的社区,提供了大量的扩展(Extensions)。这些扩展涵盖了数据库集成、用户认证、表单处理、RESTful API 构建等方方面面,可以轻松地为 Flask 应用添加各种复杂功能。
  4. 文档清晰: Flask 的官方文档质量很高,提供了详细的指南和API参考。
  5. 适用于多种场景: Flask 不仅适合构建小型应用或原型,也常用于构建微服务、API接口,甚至在一些大型项目中作为基础框架。

与 Django 等“全栈”框架相比,Django 提供了更多内置功能和约定(如ORM、后台管理界面等),更适合快速构建大型、复杂的应用,但学习曲线可能稍陡峭。Flask 则更像是Web开发的乐高积木,你可以自由选择和组装所需的部分。

2. 环境准备

在开始编写 Flask 应用之前,你需要确保安装了 Python,并建议创建一个独立的虚拟环境。

2.1 安装 Python

如果你的系统还没有安装 Python,请访问 Python 官网 (https://www.python.org/downloads/) 下载并安装最新版本 (推荐使用 Python 3.6 或更高版本)。安装时请注意勾选“Add Python to PATH”选项,这样你就可以在命令行中直接运行 python 命令。

2.2 创建和激活虚拟环境 (强烈推荐)

虚拟环境是一个独立的 Python 环境,可以让你为每个项目安装独立的库,避免不同项目之间的库版本冲突。这是 Python 开发的最佳实践。

打开你的终端或命令行工具,导航到你想创建项目的目录。

在 macOS 或 Linux 上:

  1. 创建一个名为 myflaskapp 的项目文件夹:
    bash
    mkdir myflaskapp
    cd myflaskapp
  2. 在项目文件夹内创建虚拟环境:
    bash
    python3 -m venv venv

    这会在当前目录下创建一个名为 venv 的文件夹,里面包含了独立的 Python 解释器和 pip。
  3. 激活虚拟环境:
    bash
    source venv/bin/activate

    激活成功后,你的命令行提示符前会显示 (venv) 字样,表明你当前处于虚拟环境中。

在 Windows 上:

  1. 创建一个名为 myflaskapp 的项目文件夹:
    bash
    mkdir myflaskapp
    cd myflaskapp
  2. 在项目文件夹内创建虚拟环境:
    bash
    python -m venv venv
  3. 激活虚拟环境:
    bash
    venv\Scripts\activate

    激活成功后,你的命令行提示符前会显示 (venv) 字样。

2.3 安装 Flask

虚拟环境激活后,使用 pip 安装 Flask:

bash
pip install Flask

稍等片刻,Flask 及其依赖就会安装完成。你可以运行 pip list 来确认 Flask 是否安装成功。

现在,你的环境已经准备好了,可以开始编写第一个 Flask 应用了!

3. 你的第一个 Flask 应用:”Hello, World!”

创建一个新的 Python 文件,比如命名为 app.py,然后在其中输入以下代码:

“`python

app.py

from flask import Flask

创建 Flask 应用实例

name 是一个特殊的 Python 变量,代表当前模块的名称。

Flask 用它来确定应用的根目录,以便找到静态文件和模板等资源。

app = Flask(name)

使用 @app.route(‘/’) 装饰器定义一个 URL 路由

当用户访问应用的根 URL (‘/’) 时,会触发下面的函数

@app.route(‘/’)
def hello_world():
# 函数返回的内容将作为 HTTP 响应发送给浏览器
return ‘Hello, World!’

检查当前脚本是否作为主程序运行

如果是,则启动 Flask 开发服务器

if name == ‘main‘:
# app.run() 启动服务器
# debug=True 开启调试模式:
# 1. 当代码修改时,服务器会自动重启
# 2. 出现错误时,浏览器会显示详细的错误信息页面
app.run(debug=True)
“`

保存文件。确保你的虚拟环境是激活状态,然后在终端中运行这个 Python 文件:

bash
python app.py

你会看到类似以下的输出:

* Serving Flask app "app" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

恭喜你!你的第一个 Flask 应用已经运行起来了。打开你的Web浏览器,访问地址 http://127.0.0.1:5000/。你将看到页面上显示 “Hello, World!”。

代码解析:

  • from flask import Flask: 导入 Flask 类。
  • app = Flask(__name__): 创建 Flask 应用实例。__name__ 参数告诉 Flask 在哪里查找资源(如模板、静态文件)。
  • @app.route('/'): 这是一个装饰器。在 Python 中,装饰器是一种修改函数行为的特殊语法。@app.route('/') 装饰器将 URL 路径 / 与紧随其后的 hello_world 函数关联起来。当用户访问 / 路径时,Flask 会执行 hello_world 函数。
  • def hello_world():: 这是一个“视图函数”(View Function)。它负责处理特定的URL请求并返回响应。在这个例子中,它返回一个简单的字符串 "Hello, World!"。Flask 会将这个字符串作为HTTP响应体发送给客户端(浏览器)。
  • if __name__ == '__main__':: 这是一个标准的 Python 习惯用法,用于判断脚本是否作为主程序直接运行。
  • app.run(debug=True): 在主程序运行时,启动 Flask 内置的开发Web服务器。debug=True 开启调试模式,这在开发阶段非常有用。服务器默认监听 127.0.0.1 (localhost) 的 5000 端口。

CTRL+C 可以停止服务器。

4. 路由 (Routing)

路由是Web框架的核心功能之一,它负责将不同的URL路径映射到不同的Python函数(视图函数)进行处理。

在 Flask 中,我们使用 @app.route() 装饰器来定义路由。

4.1 定义多个路由

你可以定义多个 @app.route() 装饰器来创建不同的页面:

“`python

app.py (在上面的代码基础上修改)

from flask import Flask

app = Flask(name)

@app.route(‘/’)
def index():
return ‘这是首页’

@app.route(‘/about’)
def about():
return ‘这是关于我们页面’

@app.route(‘/contact’)
def contact():
return ‘这是联系我们页面’

if name == ‘main‘:
app.run(debug=True)
“`

运行此代码,访问 http://127.0.0.1:5000/http://127.0.0.1:5000/abouthttp://127.0.0.1:5000/contact,你会看到对应页面的内容。

4.2 动态路由 (变量规则)

Web 应用经常需要处理带有变量的URL,例如显示特定用户或文章的页面。Flask 允许你在路由规则中定义变量部分。

“`python

app.py (在上面的代码基础上修改)

from flask import Flask

app = Flask(name)

… (前面的代码省略) …

定义一个带变量的路由

@app.route(‘/user/‘)
def show_user_profile(username):
# Flask 会将 URL 中的 部分的值作为参数传递给视图函数
return f’用户: {username}’

定义一个带类型转换器的变量路由

@app.route(‘/post/‘)
def show_post(post_id):
# 表示这个变量必须是一个整数
# post_id 参数会被 Flask 自动转换为整数类型
return f’文章 ID: {post_id}’

if name == ‘main‘:
app.run(debug=True)
“`

运行此代码,尝试访问:

  • http://127.0.0.1:5000/user/Alice 会显示 “用户: Alice”
  • http://127.0.0.1:5000/user/Bob 会显示 “用户: Bob”
  • http://127.0.0.1:5000/post/123 会显示 “文章 ID: 123”
  • http://127.0.0.1:5000/post/abc 会返回一个 404 Not Found 错误,因为 abc 不是整数。

常用的类型转换器:

  • string: 默认,接受任何不包含斜线的字符串。
  • int: 接受整数。
  • float: 接受浮点数。
  • path: 接受包含斜线的字符串(如文件路径)。
  • uuid: 接受 UUID 字符串。

5. 模板 (Templates)

在视图函数中直接返回 HTML 字符串对于简单的“Hello, World!”应用是可行的,但对于复杂的页面,这样做会变得非常繁琐且难以维护。我们需要将页面的结构 (HTML) 与应用逻辑 (Python) 分离。这就是模板引擎的作用。

Flask 默认使用 Jinja2 模板引擎。

5.1 创建模板文件

Flask 约定将模板文件放在应用根目录下的一个名为 templates 的文件夹中。

首先,在 myflaskapp 目录下创建 templates 文件夹:

bash
cd myflaskapp
mkdir templates

然后,在 templates 文件夹中创建一个 HTML 文件,比如 index.html

“`html





我的 Flask 应用

欢迎来到我的网站!

这是一个使用 Flask 和 Jinja2 模板渲染的页面。


“`

5.2 在视图函数中渲染模板

现在,修改 app.py 中的首页视图函数,让它渲染 index.html 模板:

“`python

app.py (继续修改)

from flask import Flask, render_template # 导入 render_template 函数

app = Flask(name)

@app.route(‘/’)
def index():
# 使用 render_template() 函数渲染模板文件
return render_template(‘index.html’)

… (其他路由和 if name == ‘main‘: 部分不变) …

“`

运行 python app.py,访问 http://127.0.0.1:5000/。你将看到 index.html 文件的内容被渲染并显示在浏览器中。

5.3 向模板传递数据

模板最有用的地方在于可以动态地显示数据。你可以在 render_template() 函数中以关键字参数的形式将 Python 变量传递给模板。

修改 app.py

“`python

app.py (继续修改)

from flask import Flask, render_template

app = Flask(name)

@app.route(‘/’)
def index():
# 定义一些数据
title = “我的 Flask 应用首页”
greeting = “你好!”
user = {“name”: “游客”, “is_logged_in”: False}
items = [“商品A”, “商品B”, “商品C”]

# 将数据传递给模板
return render_template('index.html',
                       page_title=title,
                       message=greeting,
                       current_user=user,
                       item_list=items)

… (其他路由和 if name == ‘main‘: 部分不变) …

“`

修改 templates/index.html,使用 Jinja2 语法来显示这些数据:

“`html





{{ page_title }}

{{ message }} {{ current_user.name }}!

{% if current_user.is_logged_in %}

欢迎回来!

{% else %}

登录注册

{% endif %}

商品列表:

    {% for item in item_list %}

  • {{ item }}
  • {% endfor %}

这是一个使用 Flask 和 Jinja2 模板渲染的页面。


“`

Jinja2 基本语法:

  • {{ variable }}: 用于输出变量的值。
  • {% statement %}: 用于控制结构,如 if/endif, for/endfor, block/endblock 等。
  • {# comment #}: 用于模板注释,不会渲染到最终的 HTML 中。

运行 python app.py,访问 http://127.0.0.1:5000/,你会看到动态生成的内容。

5.4 模板继承

大型应用中,很多页面会有相同的结构(如头部、导航栏、底部)。模板继承可以避免重复代码。

创建一个基础模板,比如 templates/base.html

“`html






{% block title %}{% endblock %} – 我的应用 {# 链接静态文件 #}

我的网站


{% block content %}{% endblock %}

© 2023 我的应用


“`

注意: {{ url_for('static', filename='style.css') }}{{ url_for('index') }} 都是 Jinja2 的内置函数,url_for() 用于生成指定视图函数或静态文件的 URL,非常有用,可以避免硬编码URL。

现在,修改 index.html 和其他模板,继承 base.html

“`html

{% extends ‘base.html’ %} {# 指明继承哪个模板 #}

{% block title %}首页{% endblock %} {# 填充 base.html 中定义的 title block #}

{% block content %} {# 填充 base.html 中定义的 content block #}

{{ message }} {{ current_user.name }}!

{% if current_user.is_logged_in %}
    <p>欢迎回来!</p>
{% else %}
    <p>请 <a href="#">登录</a> 或 <a href="#">注册</a>。</p>
{% endif %}

<h2>商品列表:</h2>
<ul>
    {% for item in item_list %}
        <li>{{ item }}</li>
    {% endfor %}
</ul>

{% endblock %}
“`

你可以为 about.htmlcontact.html 创建类似的文件,它们也继承 base.html 并只填充各自特有的内容。

6. 静态文件 (Static Files)

Web 应用通常需要一些静态文件,如 CSS 样式表、JavaScript 脚本、图片等。Flask 约定将这些文件放在应用根目录下的一个名为 static 的文件夹中。

6.1 创建静态文件

myflaskapp 目录下创建 static 文件夹:

bash
cd myflaskapp
mkdir static

static 文件夹中创建一个 CSS 文件,比如 style.css

“`css
/ static/style.css /
body {
font-family: sans-serif;
margin: 20px;
background-color: #f0f0f0;
}

header {
background-color: #333;
color: white;
padding: 10px 0;
text-align: center;
}

nav a {
color: white;
margin: 0 10px;
text-decoration: none;
}

main {
margin-top: 20px;
padding: 15px;
background-color: white;
border-radius: 8px;
}

footer {
margin-top: 20px;
text-align: center;
color: #555;
font-size: 0.9em;
}
“`

6.2 在模板中引用静态文件

在模板中使用 url_for() 函数来生成静态文件的URL,这样 Flask 就能正确找到它们:

html
{# 在 base.html 或其他模板的 <head> 部分 #}
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

url_for('static', filename='style.css') 会生成指向 /static/style.css 的URL。

运行 python app.py 并刷新页面,你应该能看到页面应用了 style.css 的样式。

7. 处理 HTTP 请求方法 (GET, POST)

Web 应用不仅展示信息,还需要处理用户输入,这通常涉及到不同的 HTTP 请求方法。最常见的是 GET (获取数据) 和 POST (提交数据)。

默认情况下,@app.route() 只响应 GET 请求。你可以通过 methods 参数指定支持的请求方法:

“`python

app.py (继续修改)

from flask import Flask, render_template, request # 导入 request 对象

app = Flask(name)

… (其他路由和模板设置不变) …

定义一个处理表单的路由,支持 GET 和 POST 方法

@app.route(‘/login’, methods=[‘GET’, ‘POST’])
def login():
# 如果是 POST 请求,处理表单数据
if request.method == ‘POST’:
# request.form 是一个字典,包含 POST 请求中的表单数据
username = request.form.get(‘username’) # 使用 get() 方法更安全,即使键不存在也不会出错
password = request.form.get(‘password’)

    # 这里可以添加验证用户名和密码的逻辑
    if username == 'admin' and password == 'password': # 简单的示例验证
        # 登录成功,通常会进行重定向
        from flask import redirect, url_for # 导入重定向函数
        return redirect(url_for('index')) # 重定向到首页
    else:
        # 登录失败,重新渲染登录页面并显示错误信息
        error = '无效的用户名或密码'
        return render_template('login.html', error=error)

# 如果是 GET 请求,显示登录表单
return render_template('login.html')

… (if name == ‘main‘: 部分不变) …

“`

7.1 创建登录表单模板

templates 文件夹中创建 login.html

“`html

{% extends ‘base.html’ %}

{% block title %}登录{% endblock %}

{% block content %}

用户登录

{# 如果存在错误信息,显示出来 #}
{% if error %}
    <p style="color: red;">{{ error }}</p>
{% endif %}

{# HTML 表单,method="POST" 表示使用 POST 方法提交 #}
{# action="/login" 表示将数据提交到 /login 这个 URL #}
<form method="POST" action="{{ url_for('login') }}">
    <div>
        <label for="username">用户名:</label>
        {# input 的 name 属性 (username, password) 与 request.form 中的键对应 #}
        <input type="text" id="username" name="username" required>
    </div>
    <br>
    <div>
        <label for="password">密码:</label>
        <input type="password" id="password" name="password" required>
    </div>
    <br>
    <div>
        <button type="submit">登录</button>
    </div>
</form>

{% endblock %}
“`

运行 python app.py,访问 http://127.0.0.1:5000/login

  • 首次访问会显示登录表单 (GET 请求)。
  • 填写用户名和密码后提交表单,会发送 POST 请求到 /login
  • Flask 应用会通过 request.method 判断是 POST 请求,然后从 request.form 中获取数据进行处理。
  • 处理结果可能是重定向到首页 (redirect(url_for('index'))) 或重新显示登录页面并带上错误信息。

7.2 request 对象

request 对象是 Flask 中一个非常重要的全局对象,它提供了访问客户端请求信息的方法。你需要在视图函数中通过 from flask import request 导入它。

request 对象常用的属性:

  • request.method: 请求方法(如 ‘GET’, ‘POST’, ‘PUT’, ‘DELETE’)。
  • request.form: 一个字典,包含 POST 请求中的表单数据(来自 Content-Type 为 application/x-www-form-urlencodedmultipart/form-data 的请求体)。
  • request.args: 一个字典,包含 URL 中的查询参数(GET 请求中 ?key=value&key2=value2 的部分)。
  • request.json: 如果请求的 Content-Type 是 application/json,这个属性将包含解析后的 JSON 数据。常用于构建 API。
  • request.headers: 包含请求头信息的字典。
  • request.cookies: 包含客户端发送的 cookie 的字典。
  • request.files: 包含上传文件的字典。
  • request.remote_addr: 客户端的 IP 地址。

8. 调试 (Debugging)

在开发过程中,难免会遇到错误。Flask 提供了强大的调试功能。

8.1 debug=True

app.run(debug=True) 中开启调试模式是最基本的调试手段。它带来了两大好处:

  1. 自动重载 (Auto-reloader): 当你修改 Python 代码并保存时,开发服务器会自动检测到变化并重启,无需手动停止和再次运行。
  2. 交互式调试器 (Interactive Debugger): 当应用发生错误时,浏览器中会显示一个详细的错误信息页面,其中包含堆栈跟踪。更重要的是,你可以在出错的那个点打开一个交互式的 Python 控制台,检查变量的值,执行代码片段等。

注意: 绝对不要 在生产环境中开启 debug=True,因为它会暴露你的代码细节,存在安全风险。生产环境应使用更健壮的Web服务器(如 Gunicorn, uWSGI)来运行 Flask 应用。

8.2 使用 print()

最简单的调试方法仍然是使用 print() 函数在视图函数中输出变量的值,然后在运行服务器的终端窗口中查看输出。

8.3 IDE 调试器

如果你使用 PyCharm、VS Code 等集成开发环境 (IDE),它们通常都提供了强大的图形化调试器,允许你在代码中设置断点,单步执行,检查变量状态等,这比使用 print() 更高效。

9. Flask 扩展 (Extensions)

Flask 的微核心设计使得它非常灵活,而 Flask 扩展则弥补了核心功能的不足。社区提供了大量高质量的扩展,用于处理数据库、用户认证、表单、REST API、缓存等等。

一些常用的 Flask 扩展:

  • Flask-SQLAlchemy: 集成 SQLAlchemy ORM,简化数据库操作。
  • Flask-migrate: 集成 Alembic 进行数据库模式迁移。
  • Flask-WTF: 集成 WTForms,简化表单处理和验证。
  • Flask-Login: 提供用户会话管理和认证功能。
  • Flask-RESTful / Flask-RESTx: 简化构建 RESTful API。
  • Flask-Mail: 方便地发送电子邮件。
  • Flask-Caching: 为应用添加缓存功能。

使用扩展通常通过 pip install Flask-ExtensionName 安装,然后在代码中导入并初始化扩展,将其关联到你的 Flask 应用实例。学习如何使用这些扩展是深入学习 Flask 的重要一步。

10. 进一步探索:构建更复杂的应用

学完上述基础知识,你已经具备了构建简单 Flask 应用的能力。要构建更复杂的应用,你可以继续学习:

  • 数据库集成: 学习使用 Flask-SQLAlchemy 将数据存储到数据库中。
  • 表单处理和验证: 学习使用 Flask-WTF 创建和验证用户提交的表单。
  • 用户认证和授权: 学习使用 Flask-Login 管理用户登录状态和访问权限。
  • 应用结构化: 学习如何将大型应用拆分为多个模块 (Blueprints) 来组织代码。
  • 错误处理: 定义自定义的 404、500 等错误页面。
  • Contexts (应用上下文和请求上下文): 理解 Flask 的上下文机制,这是理解 requestg 等对象工作原理的关键。
  • 命令行界面 (CLI): 使用 Flask CLI 或 Flask-Script 创建自定义命令,方便开发和管理应用。
  • 单元测试: 学习如何为你的 Flask 应用编写自动化测试。
  • 部署: 了解如何将你的 Flask 应用部署到生产服务器上。

11. 总结

Flask 是一个优秀的 Python Web 微框架,它以其简洁、灵活和易于扩展的特性,成为许多开发者构建Web应用、API服务和微服务的首选。

通过本文的学习,你已经掌握了 Flask 的核心概念:

  • 如何创建一个基本的 Flask 应用
  • 如何定义路由来处理不同的URL请求
  • 如何使用 Jinja2 模板引擎渲染动态 HTML 页面,并向模板传递数据
  • 如何利用模板继承提高代码复用性
  • 如何配置和引用静态文件 (CSS, JS, 图片)
  • 如何处理不同的 HTTP 请求方法 (GET, POST) 并获取表单数据或查询参数
  • 如何利用 debug=True 进行开发阶段的调试
  • 了解了 Flask 扩展生态系统的重要性

这仅仅是 Flask 世界的冰山一角。Web 开发是一个广阔的领域,还有很多东西等待你去探索。

接下来做什么?

最好的学习方法是实践!尝试使用你学到的知识,构建一个小型项目:

  • 一个简单的待办事项列表应用
  • 一个展示你的作品的个人网站
  • 一个简单的博客(虽然没有数据库还不能持久化文章)
  • 一个返回 JSON 数据的简单 API

在实践中遇到问题,查阅 Flask 官方文档 (https://flask.palletsprojects.com/) 或搜索在线资源,这是提升技能最有效的方式。

希望这篇文章能为你打开 Flask 世界的大门,祝你在使用 Flask 构建Web应用的旅程中愉快!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部