Flask(一) 基本概念

发布于:2025-06-30 ⋅ 阅读:(15) ⋅ 点赞:(0)

🚀 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

网站公告

今日签到

点亮在社区的每一天
去签到