Flask 框架基础介绍 – wiki基地


Flask 框架基础介绍:轻量级但功能强大的 Python Web 开发利器

随着互联网技术的飞速发展,Web 应用已经成为我们日常生活中不可或缺的一部分。无论是简单的个人博客,复杂的电商平台,还是提供 API 服务的后端,都需要强大的 Web 框架来支撑开发。在众多 Web 框架中,Python 语言的 Flask 框架凭借其轻量、灵活和易学的特点,赢得了大量开发者的青睐。

本文将带您深入了解 Flask 框架的基础知识,从其核心理念、环境搭建,到路由、请求、响应、模板、静态文件等核心组件,旨在为您构建一个清晰的 Flask 开发入门蓝图。

1. 什么是 Flask?理解其“微”理念

Flask 是一个使用 Python 语言编写的微型 Web 应用框架。这里的“微型”并非指功能少,而是指 Flask 核心非常简洁,它只提供了构建 Web 应用最基本的功能:请求路由(Routing)和 Werkzeug WSGI 工具集。

  • 请求路由 (Routing): 将不同的 URL 地址映射到 Python 函数上,当用户访问某个 URL 时,执行对应的函数并返回结果。
  • Werkzeug WSGI 工具集: Werkzeug 是一个强大的 WSGI(Web Server Gateway Interface,Web服务器网关接口)工具库。WSGI 是 Python 定义的 Web 服务器与 Web 应用之间的标准接口。Werkzeug 提供了处理请求、响应、Header、Cookie 等底层 Web 协议的工具,Flask 利用它来与 Web 服务器进行通信。

Flask 之所以被称为“微”框架,是因为它不包含许多全功能框架(如 Django)内置的功能,例如:

  • 数据库抽象层(ORM)
  • 表单验证
  • 用户认证
  • 缓存系统
  • 后台管理界面

这些功能并非 Flask 不需要,而是它将选择权交给了开发者。Flask 鼓励使用第三方库来集成这些功能。例如,您可以使用 SQLAlchemy 作为 ORM,WTForms 进行表单验证,Flask-Login 处理用户认证等等。这种设计哲学使得 Flask 核心保持精简,开发者可以根据项目需求自由选择最合适的组件,避免了框架本身的“锁定”和不必要的开销。

这使得 Flask 既可以用于快速开发小型应用或 API 服务,也可以通过集成丰富的第三方扩展构建大型复杂系统。其灵活性是其最大的魅力之一。

2. 为什么选择 Flask?其核心优势

Flask 的“微”理念带来了许多优势,使得它在特定场景下成为非常受欢迎的选择:

  • 易学易用: Flask 的 API 设计简洁直观,核心概念不多,对于新手非常友好,可以很快上手并构建一个简单的 Web 应用。
  • 代码结构清晰: 由于没有强加太多的约定和规则,开发者可以自由组织代码结构,保持代码的清晰和整洁。这对于理解和维护代码非常有帮助。
  • 高度灵活: 您可以自由选择使用的数据库、模板引擎、缓存方案、认证方式等。这种自由度使得 Flask 能够适应各种不同的项目需求和技术栈。
  • 强大的可扩展性: Flask 拥有一个庞大的社区和丰富的第三方扩展库(Flask-Extensions)。几乎您能想到的常见 Web 开发功能,都有对应的 Flask 扩展可以轻松集成,例如数据库操作、表单处理、用户会话管理、RESTful API 构建等等。
  • 完善的文档和活跃的社区: Flask 官方文档非常详细和清晰,是学习和查阅的重要资源。同时,Flask 社区非常活跃,遇到问题很容易找到帮助。
  • 适合小型项目和微服务: 对于只需要少量功能的应用、API 服务或者作为大型应用中的微服务,Flask 的轻量特性使其启动快、资源占用少,非常适合。

当然,Flask 也不是万能的。对于需要快速搭建一个功能完备的、包含后台管理界面的大型应用时,Django 这种全功能框架可能会更高效,因为它已经内置了许多常用功能。选择 Flask 还是 Django,取决于您的项目需求、团队经验以及偏好。但对于希望深入理解 Web 工作原理、偏好组件自由组合、或者需要快速构建轻量级服务的开发者来说,Flask 是一个极佳的选择。

3. 准备环境:安装 Python 和 Flask

开始使用 Flask 之前,您需要确保系统安装了 Python。推荐使用 Python 3.6 或更高版本。

3.1 安装 Python

访问 Python 官方网站下载并安装适合您操作系统的 Python 版本。安装时请勾选“Add Python to PATH”(如果适用),这样可以在命令行中直接使用 pythonpython3 命令。

3.2 创建和激活虚拟环境

在进行 Python 项目开发时,强烈推荐使用虚拟环境(Virtual Environment)。虚拟环境可以为每个项目创建一个独立的 Python 运行环境,避免不同项目之间的依赖冲突。

在项目目录下打开命令行或终端,执行以下命令创建虚拟环境(这里使用 Python 3 的 venv 模块):

“`bash

创建虚拟环境 (名为 ‘venv’)

python3 -m venv venv
“`

创建完成后,激活虚拟环境:

  • 在 macOS/Linux 上:
    bash
    source venv/bin/activate
  • 在 Windows 上:
    bash
    venv\Scripts\activate

激活后,您的命令行提示符前面会显示虚拟环境的名称(通常是 (venv))。现在,您在该环境中安装的所有库都只会存在于这个虚拟环境中,不会影响系统全局或其他项目。

3.3 安装 Flask

在虚拟环境激活的状态下,使用 pip 安装 Flask:

bash
pip install Flask

如果安装成功,您就可以开始使用 Flask 了。

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

按照惯例,我们从一个最简单的“Hello, World!”应用开始。

在项目目录下创建一个 Python 文件,例如 app.py,然后输入以下代码:

“`python

app.py

from flask import Flask

创建一个 Flask 应用实例

name 是一个特殊的变量,它被设置为当前模块的名称。

Flask 使用这个参数来确定应用根目录,以便找到资源文件(如模板和静态文件)。

app = Flask(name)

使用路由装饰器 @app.route() 将 URL ‘/’ 映射到 index() 函数

@app.route(‘/’)
def index():
“””首页视图函数,当访问根 URL 时执行”””
return ‘Hello, World!’ # 返回一个简单的字符串作为响应体

Python 程序的入口点

只有当 app.py 文件被直接运行时(而不是作为模块导入时),才会执行 app.run()

if name == ‘main‘:
# 运行 Flask 应用
# debug=True 开启调试模式,开发阶段非常有用
# 在调试模式下,服务器会在代码修改后自动重载,并在发生错误时提供详细的错误信息
app.run(debug=True)
“`

保存文件后,在激活了虚拟环境的命令行中运行这个文件:

bash
python app.py

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

* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

这表示 Flask 开发服务器已经启动,并且正在监听本地的 5000 端口。打开您的 Web 浏览器,访问 http://127.0.0.1:5000/,您应该会看到页面上显示“Hello, World!”。

恭喜您!您已经成功运行了第一个 Flask 应用。

代码解释:

  1. from flask import Flask: 导入 Flask 类。
  2. app = Flask(__name__): 创建 Flask 应用的实例。__name__ 参数是必需的,Flask 用它来定位应用资源。
  3. @app.route('/'): 这是一个装饰器(Decorator),它是 Python 的一个语法特性。它告诉 Flask,当用户访问应用的根 URL(/)时,应该调用紧随其后的 index() 函数。我们将 URL 映射到函数的过程称为路由
  4. def index():: 这是一个 Python 函数,称为视图函数。它负责处理来自特定 URL 的请求。
  5. return 'Hello, World!': 视图函数需要返回一个响应体。在这个简单的例子中,返回一个字符串。Flask 会将这个字符串包装成一个完整的 HTTP 响应(默认状态码 200 OK,内容类型 text/html)。
  6. if __name__ == '__main__': app.run(debug=True): 这是一个标准的 Python 模式,确保 app.run() 只在直接运行脚本时执行。app.run() 启动 Flask 的内置开发服务器。debug=True 开启调试模式,这在开发阶段非常有用,因为它会在代码改变时自动重启服务器,并在发生错误时提供详细的堆栈跟踪信息。注意:开发服务器不适合用于生产环境!

5. 深入核心:路由、请求与响应

理解如何在 Flask 中处理路由、请求和响应是构建 Web 应用的基础。

5.1 路由 (Routing)

路由是将 URL 地址与 Python 函数关联起来的过程。除了根 URL,您还可以定义其他路由:

“`python
@app.route(‘/about’)
def about():
return ‘This is the About page.’

@app.route(‘/contact’)
def contact():
return ‘Contact us here.’
“`

现在访问 http://127.0.0.1:5000/about 会显示“This is the About page.”,访问 http://127.0.0.1:5000/contact 会显示“Contact us here.”。

动态路由

路由还可以包含变量,实现动态 URL:

“`python
@app.route(‘/user/‘)
def show_user_profile(username):
# username 变量从 URL 中获取,并作为参数传递给函数
return f’User: {username}’

@app.route(‘/post/‘)
def show_post(post_id):
# post_id 被自动转换为整数类型
return f’Post ID: {post_id}’
“`

访问 /user/john 会显示“User: john”,访问 /post/123 会显示“Post ID: 123”。<username><int:post_id> 是 URL 变量。<int:post_id> 中的 int: 是一个转换器(Converter),确保变量是指定类型(这里是整数)。Flask 内置的转换器包括 string (默认), int, float, path (包含斜杠), uuid

指定请求方法

默认情况下,路由响应所有 HTTP 方法(GET, POST 等)。您可以通过 methods 参数限制允许的请求方法:

python
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# 处理 POST 请求(例如用户提交表单)
return 'Processing login...'
else:
# 处理 GET 请求(显示登录表单)
return 'Show login form'

5.2 请求 (Request)

在 Flask 中,通过导入 request 对象来访问客户端发送的请求信息。request 对象是一个全局对象,但在不同的请求中包含不同的数据,这得益于 Flask 的上下文机制。

request 对象提供了访问请求数据的属性和方法:

  • request.method: 请求方法 (GET, POST, PUT, DELETE 等)。
  • request.args: URL 中的查询参数(GET 请求参数),一个 MultiDict 对象。例如 /search?q=flask&page=1,可以通过 request.args.get('q') 获取 ‘flask’。
  • request.form: 表单提交的数据(POST 请求参数),一个 MultiDict 对象。例如处理 HTML 表单提交的数据。
  • request.data: 原始请求体数据,通常用于非表单提交的数据(如 JSON 或 XML)。
  • request.json: 如果请求的 Content-Type 是 application/json,则此属性包含解析后的 JSON 数据。
  • request.headers: 请求头信息,一个 EnvironHeaders 对象。
  • request.cookies: 客户端的 Cookie。
  • request.files: 上传的文件,一个 MultiDict 对象。
  • request.remote_addr: 客户端的 IP 地址。
  • request.url: 完整的请求 URL。
  • request.path: 请求路径(不包含域名和查询参数)。

以下是一个处理表单提交的例子:

“`python
from flask import Flask, request, render_template_string

app = Flask(name)

简单 HTML 表单模板 (为了演示,直接用字符串表示)

HTML_FORM = “””




“””

@app.route(‘/’)
def index():
return render_template_string(HTML_FORM) # 渲染上面的 HTML 表单

@app.route(‘/greet’, methods=[‘POST’])
def greet():
if request.method == ‘POST’:
name = request.form.get(‘name’) # 获取表单中名为 ‘name’ 的字段值
if name:
return f’Hello, {name}!’
else:
return ‘Hello, Guest!’

if name == ‘main‘:

app.run(debug=True)

“`

在这个例子中,当用户提交 / 页面上的表单时,请求会以 POST 方法发送到 /greet URL。greet() 函数通过 request.form.get('name') 获取用户在输入框中输入的名字。

5.3 响应 (Response)

视图函数需要返回一个响应,Flask 会将其发送给客户端。返回值的类型可以是:

  1. 字符串: Flask 会将其包装成一个包含 text/html 内容类型的响应。
    python
    return 'Hello, World!'
  2. 元组: (响应体, 状态码, 响应头)(响应体, 状态码)(响应体, 响应头)。这提供了更多控制权。
    python
    return 'Not Found', 404 # 返回 404 状态码
    return 'Custom Header', {'X-My-Header': 'Flask'} # 添加自定义响应头
    return 'Created', 201, {'Location': '/new_resource'} # 结合状态码和响应头
  3. Response 对象: 使用 make_response 或其他 Response 类(如 jsonify)创建的响应对象,提供最大的控制权。
    “`python
    from flask import make_response, jsonify

    @app.route(‘/custom_response’)
    def custom_response():
    response = make_response(‘This is a custom response’)
    response.headers[‘Content-Type’] = ‘text/plain’
    response.status_code = 202 # Accepted
    return response

    @app.route(‘/json_data’)
    def json_data():
    data = {‘name’: ‘Flask’, ‘version’: ‘2.0’}
    return jsonify(data) # 返回 JSON 格式数据,Content-Type 设为 application/json
    ``jsonify` 是构建 RESTful API 时常用的函数,它会自动将 Python 字典或列表序列化为 JSON 格式,并设置正确的 Content-Type。

6. 模板 (Templating):分离逻辑与视图

将 HTML 代码直接写在 Python 字符串中很快就会变得难以维护。Web 应用通常使用模板引擎来生成动态 HTML 页面,将页面的结构和内容与 Python 逻辑分离开来。Flask 默认集成了 Jinja2 模板引擎,这是一个功能强大且易于使用的模板引擎。

6.1 设置模板目录

在 Flask 应用的根目录下,创建一个名为 templates 的文件夹。所有模板文件都应该放在这个文件夹中。

6.2 使用 render_template()

在视图函数中,使用 render_template() 函数来渲染模板。您需要从 flask 模块导入它。

“`python
from flask import Flask, render_template

app = Flask(name)

@app.route(‘/hello/‘)
def hello(name=None):
# 渲染 templates 目录下的 hello.html 文件
# 并将 Python 变量 name 传递给模板,在模板中可以通过 name 访问
return render_template(‘hello.html’, name=name)

if name == ‘main‘:

app.run(debug=True)

“`

6.3 编写 Jinja2 模板

templates 文件夹下创建 hello.html 文件:

“`html




Hello Page


{% if name %} {# Jinja2 控制流:如果 name 变量存在 #}

Hello, {{ name }}!

{# Jinja2 变量:显示 name 变量的值 #}
{% else %} {# 否则 #}

Hello, Guest!

{% endif %}

This is a template example.


“`

Jinja2 基础语法:

  • {{ variable }}: 用于输出变量的值。
  • {% control_structure %}: 用于控制结构,如 if/endif, for/endfor, block/endblock 等。
  • {# comment #}: 用于模板注释。

现在访问 /hello/Alice 会看到页面显示“Hello, Alice!”,访问 /hello/ (如果路由允许 name 为空,或者定义了 /hello/ 路由指向同一个函数并提供默认值) 会显示“Hello, Guest!”。

模板的使用大大提高了代码的可读性和可维护性,使得前端设计和后端逻辑可以更好地分离。

7. 静态文件 (Static Files):CSS, JavaScript 和图片

Web 应用通常需要提供静态文件,如 CSS 样式表、JavaScript 脚本文件和图片等。Flask 会自动为这些文件设置服务。

7.1 设置静态文件目录

在 Flask 应用的根目录下,创建一个名为 static 的文件夹。所有静态文件都应该放在这个文件夹中。例如:

your_flask_app/
├── app.py
├── templates/
│ └── hello.html
└── static/
├── css/
│ └── style.css
├── js/
│ └── main.js
└── images/
└── logo.png

7.2 在模板中引用静态文件

在 Jinja2 模板中,使用 url_for() 函数来生成静态文件的 URL。url_for() 函数会查找名为 static 的端点(Flask 自动为静态文件夹创建的端点),并根据 filename 参数查找文件路径。

例如,在 hello.html 中引用 static/css/style.css

“`html




Hello Page
{# 引用静态 CSS 文件 #}


{# 引用静态图片 #}
Logo

{# 引用静态 JavaScript 文件 #}


“`

url_for('static', filename='css/style.css') 会生成正确的 URL,例如 /static/css/style.css。使用 url_for 的好处是,即使将来改变了静态文件的存放路径或者配置,链接也会自动更新,避免硬编码 URL。

8. 配置 (Configuration)

Flask 应用的配置可以通过多种方式进行,例如设置调试模式、数据库连接字符串、密钥等。

最简单的方式是直接在 app 对象上设置配置项:

python
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'super secret key' # 用于会话、CSRF 保护等,生产环境中必须设置且复杂
app.config['DATABASE_URL'] = 'sqlite:///tmp/test.db'

其他常用的配置方式包括:

  • 从配置类加载:
    “`python
    class Config:
    DEBUG = False
    SECRET_KEY = ‘prod secret key’

    class DevelopmentConfig(Config):
    DEBUG = True

    app.config.from_object(DevelopmentConfig) # 加载 DevelopmentConfig 类中的配置
    * **从配置文件加载:**python

    config.py

    DEBUG = False
    SECRET_KEY = ‘file secret key’
    DATABASE_URL = ‘postgresql://user:password@host/db’

    app.py

    app.config.from_pyfile(‘config.py’)
    ``
    * **从环境变量加载:** Flask-DotEnv 等扩展可以帮助从
    .env` 文件加载环境变量。

推荐使用配置类或配置文件来管理配置,特别是区分开发、测试和生产环境的配置。密钥 (SECRET_KEY) 等敏感信息在生产环境中应通过环境变量传递,而不是直接写在代码或配置文件中。

9. Flask 扩展 (Extensions):让 Flask 更强大

Flask 核心功能非常精简,但其真正的力量来自于丰富的第三方扩展。这些扩展为 Flask 增加了数据库操作、表单处理、用户认证、API 构建、邮件发送等常见 Web 开发功能。

一些流行的 Flask 扩展包括:

  • Flask-SQLAlchemy: 集成 SQLAlchemy ORM,简化数据库操作。
  • Flask-WTF: 集成 WTForms,方便创建和验证 Web 表单。
  • Flask-Login: 处理用户会话管理,包括用户登录、注销和记住我功能。
  • Flask-RESTful / Flask-RESTx: 帮助构建 RESTful API。
  • Flask-Migrate: 集成 Alembic 进行数据库迁移。
  • Flask-Mail: 发送邮件。

使用扩展通常遵循类似的模式:先通过 pip 安装扩展,然后在应用中初始化扩展,并将其绑定到 Flask 应用实例上。例如,使用 Flask-SQLAlchemy:

bash
pip install Flask-SQLAlchemy

“`python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(name)
app.config[‘SQLALCHEMY_DATABASE_URI’] = ‘sqlite:////tmp/test.db’ # 配置数据库连接
app.config[‘SQLALCHEMY_TRACK_MODIFICATIONS’] = False # 关闭修改跟踪,减少开销
db = SQLAlchemy(app) # 初始化扩展并绑定到应用

定义一个简单的模型

class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)

def __repr__(self):
    return '<User %r>' % self.username

在应用上下文中创建数据库表 (开发阶段)

from app import app, db, User # 假设上面的代码在 app.py 中

with app.app_context():

db.create_all()

“`

通过合理选择和使用这些扩展,您可以快速构建功能丰富的 Web 应用,而无需从零开始实现所有功能。

10. 运行与部署 (Running & Deployment)

前面我们使用了 Flask 内置的开发服务器来运行应用 (app.run(debug=True))。这在开发阶段非常方便,但它不是为生产环境设计的。

10.1 开发服务器 (flask run)

推荐使用 Flask 官方提供的 flask 命令行工具来运行开发服务器。在项目根目录(app.py 所在目录),激活虚拟环境后,简单地运行:

bash
export FLASK_APP=app.py # 设置环境变量告诉 Flask 入口文件
flask run

如果文件名为 wsgi.pyapp.py 并且应用实例名为 appapplication,通常可以省略 export FLASK_APP

flask run 命令提供了更多选项,例如指定端口 (flask run --port 8000) 或主机 (flask run --host 0.0.0.0 使外部可访问,但仅限开发用)。它也会自动检测文件修改并重启服务器(当 FLASK_ENV=development 时,或设置 DEBUG=True)。

10.2 生产环境部署 (WSGI 服务器)

在生产环境中,需要使用专门的 WSGI 服务器来运行 Flask 应用。常见的 WSGI 服务器有 Gunicorn, uWSGI 等。这些服务器更健壮、性能更高,能够处理并发请求和管理进程。

部署 Flask 应用通常涉及以下步骤:

  1. 选择并安装一个生产级 WSGI 服务器(如 pip install gunicorn)。
  2. 使用 WSGI 服务器启动您的 Flask 应用。例如,使用 Gunicorn 启动 app.py 中的 app 实例:
    bash
    gunicorn -w 4 app:app # 启动 4 个工作进程运行 app.py 中的 app 应用实例
  3. 通常在 WSGI 服务器前面还会放置一个反向代理服务器,如 Nginx 或 Apache,用于处理静态文件、SSL 终止、负载均衡等。

详细的部署过程会根据您选择的服务器、操作系统和部署环境(如 Docker, PaaS 平台)而有所不同。

11. 进一步学习

本文介绍了 Flask 的基础知识,帮助您迈出了第一步。要成为一名熟练的 Flask 开发者,您还需要学习更多内容:

  • 蓝图 (Blueprints): 用于组织大型应用的代码,将应用划分为可重用的组件。
  • 上下文 (Contexts): 理解请求上下文和应用上下文的工作原理对于理解 Flask 如何处理请求和访问全局资源非常重要。
  • 错误处理: 如何捕获和处理各种 HTTP 错误和异常。
  • 测试: 学习如何为您的 Flask 应用编写单元测试和集成测试。
  • 安全性: 了解常见的 Web 安全威胁(如 XSS, CSRF)以及 Flask 和相关扩展提供的防护措施。
  • 常用的 Flask 扩展: 深入学习上面提到的一些重要扩展的使用。
  • 大型应用结构: 学习如何使用蓝图、工厂模式等构建可维护的大型 Flask 应用。

Flask 的官方文档是最好的学习资源,务必花时间仔细阅读。此外,网上有大量的教程、博客和开源项目,可以供您参考学习。

12. 总结

Flask 是一个优雅、轻量且高度灵活的 Python Web 框架。它不强制您遵循特定的模式,而是提供核心功能,让您自由选择所需的工具和库。从“Hello, World!”到处理请求、渲染模板和使用扩展,本文为您勾勒了 Flask 开发的基础轮廓。

理解 Flask 的“微”理念和其核心组件(路由、请求、响应、模板、静态文件)是掌握它的关键。通过利用丰富的第三方扩展,您可以构建从简单 API 到复杂 Web 应用的各种项目。

Flask 是一个优秀的入门级框架,也能胜任生产级应用的开发。如果您希望快速入门 Web 开发,或者偏好灵活自由的技术栈,那么 Flask 绝对值得您投入时间去学习。

希望这篇文章能帮助您开启愉快的 Flask 开发之旅!

发表评论

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

滚动至顶部