🚀 Flask 最小可运行示例
基本结构
your_project/
├── app.py
├── templates/
│ └── index.html
└── static/
└── style.css
app.py
from flask import Flask
# 这行代码创建了一个 Flask 应用实例。__name__ 是一个特殊的 Python 变量,它在模块被直接运行时是 '__main__',在被其他模块导入时是模块的名字。
# 传递 __name__ 给 Flask 构造函数允许 Flask 应用找到和加载配置文件。
app = Flask(__name__,
template_folder="templates", # 默认就是 templates,可省略
static_folder="static") # 默认就是 static,可省略
# 这是一个装饰器,用于定义路由,用于告诉 Flask 哪个 URL 应该触发下面的函数。在这个例子中,它指定了根 URL(即网站的主页)。
# @app.route('/'):将根 URL / 映射到 hello_world 函数。
# '/' 表示根 URL。
@app.route('/')
#这是定义了一个名为 hello_world 的函数,它将被调用当用户访问根URL时。
def hello_world():
# 这行代码是 hello_world 函数的返回值。当用户访问根 URL 时,这个字符串将被发送回用户的浏览器。
return 'Hello, World!'
# 这行代码是一个条件判断,用于检查这个模块是否被直接运行,而不是被其他模块导入。如果是直接运行,下面的代码块将被执行。
if __name__ == '__main__':
# 这行代码调用 Flask 应用实例的 run 方法,启动 Flask 内置的开发服务器。debug=True 参数会启动调试模式,这意味着应用会在代码改变时自动重新加载,并且在发生错误时提供一个调试器。
app.run(debug=True,
host="127.0.0.1", # 默认值127.0.0.1,可省略
port=5000 # 默认值5000,可省略
)
若执行后报端口已经被占用,则可以换个port,比如5001,5002,也可以在终端输入
lsof -i :5008
,查看当前在运行的进程,用kill -9 <PID>
杀掉不需要的进程,释放资源
映射过程原理:
1. Flask 应用初始化
app = Flask(__name__)
这一步会创建一个 Flask 实例对象 app,它内部维护了一个 URL 路由映射表(dict 类型),用于记录每个 URL 应该调用哪个函数。
2. 装饰器 @app.route('/hello')
注册视图函数
当 Python 执行到这行代码:
@app.route('/hello')
def hello():
return '你好 Flask'
也就是调用了:
app.add_url_rule('/hello', endpoint='hello', view_func=hello)
这将把 /hello 路由路径映射到 hello() 这个函数,并记录在 Flask 应用的路由映射表中
3. 用户访问 http://localhost:5000/hello
当浏览器发出请求,Flask 会:
- 解析请求路径 /hello
- 在内部的路由表中查找是否有匹配的视图函数
- 找到后,调用你定义的 hello() 函数
4. 视图函数返回字符串 → 转为响应 Response
你的函数返回的是:return '你好 Flask'
Flask 会自动封装成 HTTP 响应对象:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
你好 Flask
总结:Flask 路由映射原理图
装饰器 @app.route('/hello')
↓
注册到 app.url_map 路由表
↓
收到 HTTP 请求: GET /hello
↓
匹配路由,调用 hello()
↓
返回字符串 → 构造成 Response → 返回给浏览器
Flask 请求生命周期(Request Lifecycle) 的可视化流程图
浏览器发起请求(HTTP 请求)
│
▼
┌─────────────────────┐
│ Flask 应用启动 │ ← app = Flask(__name__)
└─────────────────────┘
│
▼
┌─────────────────────┐
│ 路由注册阶段 │ ← @app.route(...)
└─────────────────────┘
│
▼
┌─────────────────────┐
│ 接收到 HTTP 请求 │ ← GET /hello
└─────────────────────┘
│
▼
┌─────────────────────┐
│ 请求分发与路由匹配 │ ← 查找 url_map 中的规则
└─────────────────────┘
│
▼
┌─────────────────────┐
│ 执行视图函数 │ ← hello()
└─────────────────────┘
│
▼
┌─────────────────────┐
│ 返回字符串/HTML │ ← return '你好 Flask'
└─────────────────────┘
│
▼
┌─────────────────────┐
│ 封装为 Response 对象 │ ← Flask 自动生成响应
└─────────────────────┘
│
▼
┌─────────────────────┐
│ 发回客户端浏览器 │ ← 浏览器显示页面
└─────────────────────┘
🚀 Flask 的核心概念速览
概念 | 说明 |
---|---|
Flask 应用对象 |
Web 应用的入口(app = Flask(__name__) ) |
路由 (@app.route ) |
把 URL 映射到 Python 函数 |
视图函数(View) | 响应请求的函数,返回页面/JSON |
模板(Template) | HTML 文件,使用 Jinja2 渲染动态内容 |
请求(Request) | 封装了浏览器发来的请求内容 |
响应(Response) | 服务端返回的内容(HTML、JSON、文件等) |
表单(Form) | 提交用户输入,如登录、搜索等 |
Session / Cookie | 保存用户状态 |
数据库(SQLAlchemy) | ORM,Python 对象操作数据库 |
📍 路由(URL -> 函数)
@app.route('/hello')
def hello():
return '你好 Flask'
@app.route('/hello')
:将 /hello URL 映射到 hello 函数。
带参数:
@app.route('/user/<name>')
def user(name):
return f'你好, {name}'
user
函数接收 URL 中的name
参数,并返回一个字符串响应。
📥 表单处理(GET + POST)
from flask import request
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
return f'欢迎 {username}'
return '''
<form method="post">
用户名: <input name="username">
<input type="submit">
</form>
'''
request.form.get('username')
:获取 POST 请求中表单数据的 username 字段。
📂 模板渲染(Jinja2)
Flask 使用 Jinja2 模板引擎来渲染 HTML 模板。模板允许你将 Python 代码嵌入到 HTML 中,从而动态生成网页内容。
from flask import render_template
@app.route('/welcome/<name>')
def welcome(name):
return render_template('welcome.html', username=name)
templates/welcome.html:
<h1>欢迎, {{ username }}</h1>
📍 重定向 / 闪现消息
from flask import redirect, url_for, flash
@app.route('/logout')
def logout():
flash('你已退出')
return redirect(url_for('login'))
🗃️ 静态文件(CSS / JS)
static/style.css:
body { background: #f5f5f5; }
模板中使用:
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
📍 响应对象 (Response Object)
from flask import make_response
@app.route('/custom_response')
def custom_response():
response = make_response('This is a custom response!')
response.headers['X-Custom-Header'] = 'Value'
return response
make_response
:创建一个自定义响应对象,并设置响应头 X-Custom-Header。
flask.make_response()
是 Flask 中一个非常实用的函数,用于手动构建一个完整的响应对象(Response),从而精确控制:
- 返回的内容
- 状态码
- 响应头(headers)
- Cookie 等
基本语法
from flask import make_response
response = make_response(response_body, status_code)
response.headers['Custom-Header'] = 'value'
response.set_cookie('token', 'abc123')
return response
示例 1:手动构造响应 + 设置 Cookie
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/set-cookie')
def set_cookie():
resp = make_response("Cookie 已设置!")
resp.set_cookie('username', 'root')
return resp
示例 2:返回 JSON + 自定义头部
from flask import jsonify, make_response
@app.route('/custom-json')
def custom_json():
data = {'msg': 'OK', 'status': 200}
resp = make_response(jsonify(data), 200)
resp.headers['X-App-Version'] = '1.0'
return resp
示例 3:返回文件下载
from flask import make_response, send_file
@app.route('/download')
def download():
return send_file('path/to/report.xlsx', as_attachment=True)
或自定义 Content-Disposition:
@app.route('/download-custom')
def download_custom():
with open("report.txt", "r") as f:
content = f.read()
resp = make_response(content)
resp.headers["Content-Disposition"] = "attachment; filename=report.txt"
return resp
适用场景
场景 | 说明 |
---|---|
设置 cookie/session | response.set_cookie() |
自定义响应头 | response.headers[...] = ... |
控制状态码 | make_response(..., 403) |
生成复杂响应内容 | 返回 HTML/JSON/文件等 |
📍 配置对象 (Configuration Objects)
配置对象用于设置应用的各种配置选项,如数据库连接字符串、调试模式等。可以通过直接设置或加载配置文件来配置 Flask 应用。
class Config:
DEBUG = True
SECRET_KEY = 'mysecretkey' # 用于 session、登录保护
SQLALCHEMY_DATABASE_URI = 'sqlite:///mydatabase.db'
app.config.from_object(Config)
:将 Config 类中的配置项加载到应用配置中。
📍 扩展:SQLAlchemy
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# 创建 Flask 应用
app = Flask(__name__)
# 配置 SQLite 数据库
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 建议加上这行,防止警告
# 初始化 SQLAlchemy
db = SQLAlchemy(app)
部分 | 含义 |
---|---|
'sqlite:///mydatabase.db' |
使用 SQLite 数据库,数据库文件保存在当前目录 |
SQLAlchemy(app) |
绑定 Flask 应用,初始化 ORM 引擎 |
SQLALCHEMY_TRACK_MODIFICATIONS |
关闭事件监听,提升性能,防止警告 |
📍 会话 (Sessions)
Flask 使用客户端会话来存储用户信息,以便在用户浏览应用时记住他们的状态。会话数据存储在客户端的 cookie 中,并在服务器端进行签名和加密。
from flask import session
# 自动生成的密钥
app.secret_key = 'your_secret_key_here'
@app.route('/set_session/<username>')
def set_session(username):
session['username'] = username
return f'Session set for {username}'
@app.route('/get_session')
def get_session():
username = session.get('username')
return f'Hello, {username}!' if username else 'No session data'
session 对象用于存取会话数据。
你可以使用 Python 内置的 secrets 模块生成一个强随机性的密钥。
python3 -c 'import secrets; print(secrets.token_hex())'
📍 错误处理 (Error Handling)
@app.errorhandler(404)
def page_not_found(e):
return 'Page not found', 404
@app.errorhandler(500)
def internal_server_error(e):
return 'Internal server error', 500
@app.errorhandler(404)
:定义 404 错误的处理函数,返回自定义错误页面。
📍 最常用模块导入参考
from flask import Flask, request, render_template, redirect, url_for, flash, session
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, login_user, login_required, logout_user, current_user
🛠 常用功能扩展
扩展 | 功能 |
---|---|
Flask-SQLAlchemy | ORM,数据库操作 |
Flask-WTF | 表单验证与 CSRF |
Flask-Login | 用户登录管理 |
Flask-Migrate | 数据库迁移工具 |
Flask-RESTful | 快速创建 REST API |
🚀 项目结构模板
Flask + 数据库(SQLAlchemy) 项目结构模板,适用于构建:注册登录、仪表盘、API接口等中小型 Web 项目。
✅ 目录结构示意
my_flask_app/
├── app/
│ ├── __init__.py ← 初始化 Flask 应用
│ ├── models.py ← SQLAlchemy 模型
│ ├── routes.py ← 路由和视图函数
│ ├── forms.py ← 表单验证(可选,配 Flask-WTF)
│ ├── auth.py ← 登录/注册功能(可选)
│ └── templates/ ← HTML 模板目录
│ ├── base.html
│ ├── index.html
│ └── login.html
│ └── static/ ← 静态资源(CSS/JS)
│ └── style.css
├── config.py ← 配置文件(数据库 URI、密钥等)
├── run.py ← 程序启动入口
└── requirements.txt ← 项目依赖
✅ 各部分说明与示例
1. run.py(启动入口)
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
2. app/init.py(初始化 Flask)
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config.from_object('config.Config')
db.init_app(app)
from .routes import main
app.register_blueprint(main)
return app
3. config.py
class Config:
SECRET_KEY = 'your-secret-key'
SQLALCHEMY_DATABASE_URI = 'sqlite:///mydb.sqlite3'
SQLALCHEMY_TRACK_MODIFICATIONS = False
4. app/models.py
from . import db
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password_hash = db.Column(db.String(128), nullable=False)
5. app/routes.py(视图和路由)
from flask import Blueprint, render_template, request, redirect, url_for
from .models import User
from . import db
main = Blueprint('main', __name__)
@main.route('/')
def index():
return render_template('index.html')
@main.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form['username']
password_hash = request.form['password'] # 此处应加密
user = User(username=username, password_hash=password_hash)
db.session.add(user)
db.session.commit()
return redirect(url_for('main.index'))
return render_template('register.html')
6. app/templates/base.html(模板继承)
<!doctype html>
<html lang="zh-CN">
<head>
<title>{% block title %}首页{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<header>
<a href="{{ url_for('main.index') }}">首页</a> |
<a href="{{ url_for('main.register') }}">注册</a>
</header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
✅ 初始化数据库(第一次)
# 进入 Python shell
from app import create_app, db
app = create_app()
with app.app_context():
db.create_all()
✅ 安装依赖(requirements.txt)
flask
flask_sqlalchemy
安装:
pip install -r requirements.txt
✅ 启动项目
python run.py
访问 http://localhost:5000
✅ 可选扩展(按需加入)
功能 | 扩展包 |
---|---|
登录状态管理 | Flask-Login |
表单验证 | Flask-WTF |
数据迁移 | Flask-Migrate |
REST API | Flask-RESTful |
🚀 复杂项目结构
my_flask_app/
│
├── app/
│ ├── __init__.py
│ ├── routes/
│ │ ├── __init__.py
│ │ ├── main.py # 主模块的路由。
│ │ └── auth.py # 认证相关的路由。
│ ├── models/
│ │ ├── __init__.py
│ │ └── user.py # 用户模型。
│ ├── templates/ # 存放 HTML 模板文件
│ │ ├── layout.html
│ │ └── home.html
│ └── static/ # 存放静态文件,如 CSS 和 JavaScript。
│ ├── css/
│ └── js/
│
├── config.py
├── requirements.txt
├── migrations/ # 数据库迁移文件,通常与 SQLAlchemy 相关。
│ └── ...
└── run.py