1.1 什么是Flask

Flask是一个用Python编写的轻量级Web应用框架。它被称为”微框架”,因为它不需要特定的工具或库,保持核心简单但可扩展。Flask基于Werkzeug WSGI工具包和Jinja2模板引擎。

1.1.1 Flask的特点

  • 轻量级:核心功能简洁,易于学习和使用
  • 灵活性:不强制特定的项目结构或组件
  • 可扩展:通过扩展可以添加各种功能
  • WSGI兼容:遵循WSGI标准,易于部署
  • 模板引擎:内置Jinja2模板引擎
  • 调试支持:内置开发服务器和调试器

1.1.2 Flask vs Django

特性 Flask Django
学习曲线 平缓 陡峭
项目结构 灵活 固定
内置功能 最小化 全功能
适用场景 小到中型项目 大型项目
数据库ORM 需要扩展 内置
管理界面 需要扩展 内置

1.2 Flask的核心概念

1.2.1 WSGI (Web Server Gateway Interface)

WSGI是Python Web应用和Web服务器之间的标准接口。Flask应用本质上是一个WSGI应用。

# WSGI应用的基本结构
def application(environ, start_response):
    status = '200 OK'
    headers = [('Content-type', 'text/plain')]
    start_response(status, headers)
    return [b'Hello World']

1.2.2 应用上下文和请求上下文

Flask使用上下文来管理请求级别的数据:

  • 应用上下文:存储应用级别的数据
  • 请求上下文:存储请求级别的数据
from flask import Flask, request, g

app = Flask(__name__)

@app.route('/')
def index():
    # request对象包含当前请求的信息
    user_agent = request.headers.get('User-Agent')
    # g对象用于存储请求期间的数据
    g.user = 'admin'
    return f'Hello {g.user}! Your browser is {user_agent}'

1.2.3 路由系统

Flask使用装饰器来定义URL路由:

from flask import Flask

app = Flask(__name__)

# 基本路由
@app.route('/')
def home():
    return 'Hello, Flask!'

# 带参数的路由
@app.route('/user/<username>')
def user_profile(username):
    return f'User: {username}'

# 指定HTTP方法
@app.route('/api/data', methods=['GET', 'POST'])
def api_data():
    if request.method == 'POST':
        return 'Data received'
    return 'Send data here'

# 类型转换
@app.route('/post/<int:post_id>')
def show_post(post_id):
    return f'Post ID: {post_id}'

1.3 第一个Flask应用

1.3.1 最简单的Flask应用

# app.py
from flask import Flask

# 创建Flask应用实例
app = Flask(__name__)

# 定义路由
@app.route('/')
def hello_world():
    return 'Hello, World!'

# 运行应用
if __name__ == '__main__':
    app.run(debug=True)

1.3.2 运行应用

# 方法1:直接运行Python文件
python app.py

# 方法2:使用flask命令
export FLASK_APP=app.py
export FLASK_ENV=development
flask run

# Windows PowerShell
$env:FLASK_APP = "app.py"
$env:FLASK_ENV = "development"
flask run

1.3.3 应用配置

from flask import Flask

app = Flask(__name__)

# 配置方式1:直接设置
app.config['SECRET_KEY'] = 'your-secret-key'
app.config['DEBUG'] = True

# 配置方式2:从对象加载
class Config:
    SECRET_KEY = 'your-secret-key'
    DEBUG = True
    DATABASE_URL = 'sqlite:///app.db'

app.config.from_object(Config)

# 配置方式3:从文件加载
# app.config.from_pyfile('config.py')

# 配置方式4:从环境变量加载
# app.config.from_envvar('APP_SETTINGS')

1.4 Flask应用结构

1.4.1 单文件应用

适合小型项目或原型开发:

project/
├── app.py
├── requirements.txt
└── templates/
    └── index.html

1.4.2 包结构应用

适合中大型项目:

project/
├── app/
│   ├── __init__.py
│   ├── models.py
│   ├── views.py
│   ├── forms.py
│   ├── templates/
│   └── static/
├── migrations/
├── tests/
├── config.py
├── requirements.txt
└── run.py

1.4.3 蓝图(Blueprint)结构

适合大型项目的模块化开发:

project/
├── app/
│   ├── __init__.py
│   ├── main/
│   │   ├── __init__.py
│   │   ├── views.py
│   │   └── forms.py
│   ├── auth/
│   │   ├── __init__.py
│   │   ├── views.py
│   │   └── forms.py
│   ├── api/
│   │   ├── __init__.py
│   │   └── views.py
│   ├── models.py
│   ├── templates/
│   └── static/
├── migrations/
├── tests/
├── config.py
└── run.py

1.5 Flask生态系统

1.5.1 常用扩展

  • Flask-SQLAlchemy:数据库ORM
  • Flask-Migrate:数据库迁移
  • Flask-Login:用户认证
  • Flask-WTF:表单处理
  • Flask-Mail:邮件发送
  • Flask-Admin:管理界面
  • Flask-RESTful:REST API开发
  • Flask-SocketIO:WebSocket支持
  • Flask-Caching:缓存支持
  • Flask-CORS:跨域资源共享

1.5.2 扩展安装和使用

# 安装扩展
pip install Flask-SQLAlchemy

# 使用扩展
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
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)

1.6 开发环境设置

1.6.1 虚拟环境

# 创建虚拟环境
python -m venv flask_env

# 激活虚拟环境
# Linux/Mac
source flask_env/bin/activate
# Windows
flask_env\Scripts\activate

# 安装Flask
pip install Flask

# 生成依赖文件
pip freeze > requirements.txt

1.6.2 开发工具

  • IDE:PyCharm、VS Code、Sublime Text
  • 调试:Flask内置调试器、pdb
  • 测试:pytest、unittest
  • 代码质量:flake8、black、mypy

1.6.3 项目初始化脚本

# create_project.py
import os

def create_flask_project(project_name):
    # 创建项目目录结构
    dirs = [
        f'{project_name}',
        f'{project_name}/app',
        f'{project_name}/app/templates',
        f'{project_name}/app/static',
        f'{project_name}/app/static/css',
        f'{project_name}/app/static/js',
        f'{project_name}/tests',
        f'{project_name}/migrations'
    ]
    
    for dir_path in dirs:
        os.makedirs(dir_path, exist_ok=True)
    
    # 创建基本文件
    files = {
        f'{project_name}/app/__init__.py': app_init_content,
        f'{project_name}/app/models.py': models_content,
        f'{project_name}/app/views.py': views_content,
        f'{project_name}/config.py': config_content,
        f'{project_name}/run.py': run_content,
        f'{project_name}/requirements.txt': requirements_content
    }
    
    for file_path, content in files.items():
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write(content)
    
    print(f'Flask项目 {project_name} 创建成功!')

# 文件内容模板
app_init_content = '''from flask import Flask
from config import Config

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    
    from app.views import main
    app.register_blueprint(main)
    
    return app
'''

models_content = '''# 数据模型定义
pass
'''

views_content = '''from flask import Blueprint, render_template

main = Blueprint('main', __name__)

@main.route('/')
def index():
    return 'Hello, Flask!'
'''

config_content = '''import os

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-secret-key'
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///app.db'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
'''

run_content = '''from app import create_app

app = create_app()

if __name__ == '__main__':
    app.run(debug=True)
'''

requirements_content = '''Flask==2.3.3
Flask-SQLAlchemy==3.0.5
Flask-Migrate==4.0.5
Flask-WTF==1.1.1
'''

if __name__ == '__main__':
    project_name = input('请输入项目名称: ')
    create_flask_project(project_name)

1.7 Flask应用的生命周期

1.7.1 应用启动流程

  1. 创建应用实例app = Flask(__name__)
  2. 加载配置app.config.from_object(Config)
  3. 注册蓝图app.register_blueprint(blueprint)
  4. 初始化扩展db.init_app(app)
  5. 启动服务器app.run()

1.7.2 请求处理流程

  1. 接收请求:Web服务器接收HTTP请求
  2. 创建请求上下文:Flask创建请求上下文
  3. URL路由匹配:根据URL找到对应的视图函数
  4. 执行视图函数:调用视图函数处理请求
  5. 生成响应:视图函数返回响应对象
  6. 发送响应:将响应发送给客户端
  7. 清理上下文:清理请求上下文

1.7.3 钩子函数

from flask import Flask, g, request

app = Flask(__name__)

@app.before_first_request
def before_first_request():
    """在处理第一个请求前运行"""
    print('应用启动,处理第一个请求')

@app.before_request
def before_request():
    """在每个请求前运行"""
    g.start_time = time.time()
    print(f'请求开始: {request.url}')

@app.after_request
def after_request(response):
    """在每个请求后运行"""
    duration = time.time() - g.start_time
    print(f'请求完成,耗时: {duration:.2f}秒')
    return response

@app.teardown_request
def teardown_request(exception):
    """在请求上下文销毁时运行"""
    if exception:
        print(f'请求异常: {exception}')
    print('清理请求资源')

本章小结

本章介绍了Flask的基础概念,包括:

  1. Flask特点:轻量级、灵活、可扩展的Python Web框架
  2. 核心概念:WSGI、应用上下文、请求上下文、路由系统
  3. 应用结构:从单文件到模块化的项目组织方式
  4. 生态系统:丰富的扩展库支持各种功能需求
  5. 开发环境:虚拟环境、开发工具、项目初始化
  6. 应用生命周期:启动流程、请求处理、钩子函数

Flask的设计哲学是”简单而强大”,它提供了Web开发的核心功能,同时保持了足够的灵活性让开发者可以根据需求进行扩展。

下一章预告

下一章我们将学习Flask环境搭建与开发工具,包括:

  • 详细的开发环境配置
  • 常用开发工具介绍
  • 项目结构最佳实践
  • 调试和测试环境设置
  • 部署准备工作

练习题

  1. 基础练习:创建一个简单的Flask应用,包含首页、关于页面和联系页面
  2. 路由练习:实现一个用户资料页面,支持通过用户名访问
  3. 配置练习:创建不同环境的配置文件(开发、测试、生产)
  4. 结构练习:将单文件应用重构为包结构应用
  5. 扩展练习:集成Flask-SQLAlchemy,创建一个简单的用户模型