Skip to main content
Version: 1.0

Flask

Flask 是校招后端与 AI 应用岗最常考的 Python Web 框架。核心考点:微框架理念、路由、蓝图、ORM 细节、上下文机制与 session。

微框架与路由​

Flask 自称微框架:核心只保留请求分发和路由,数据库、表单、认证全靠扩展拼装。对比 Django"全家桶"(自带 ORM/Admin/Auth),Flask 灵活、上手快、适合小型服务和 AI 应用接口层;Django 适合业务复杂、需要后台管理的中大型项目。

from flask import Flask, url_for

app = Flask(__name__)

@app.route("/user/<int:uid>")
def user(uid):
return f"user {uid}"

with app.test_request_context():
url_for("user", uid=42) # "/user/42":反查路由
  • @app.route 注册路由,<int:uid> 转换器限定类型。
  • url_for 用视图函数名反查 URL:改路由不用全局搜替换;还能自动处理转义和附加查询参数——这就是它比手写路径好的原因。

末尾斜杠是单向的:定义 /about/(带斜杠)时访问 /about 会 301 重定向补上;但定义 /about 时访问 /about/ 直接 404。带斜杠像"目录",Flask 替你宽容;反向不宽容,避免 URL 二义性。

配置​

四种加载方式:直接赋值 app.config['DEBUG'] = True、app.config.from_object(...)(从类/模块)、from_pyfile(从 py 文件)、from_envvar(从环境变量指定的文件路径)。DEBUG 线上绝不能开:带交互式调试器,错误页面可以执行任意代码。

Jinja2 模板​

三种定界符:{{ 变量 }}、{% 语句 %}、{# 注释 #}。

include 与 extends 的区别:

  • {% include 'nav.html' %}:把子模板内容近似复制进当前位置,各自独立。
  • {% extends 'base.html' %} + {% block content %}:真正的继承,子模板只覆写 block。

注意:block 之外的内容不会被渲染——继承模式下子模板只有 block 里的东西才生效,这是新手常踩的坑。{{ super() }} 可在子 block 中保留父 block 的内容。

蓝图(Blueprint)​

蓝图把应用拆成模块:每个业务域一个蓝图,各自注册路由、模板目录、静态目录。

# api/auth.py
from flask import Blueprint
auth_bp = Blueprint("auth", __name__, url_prefix="/auth")

@auth_bp.route("/login")
def login(): ...
# app.py
from api.auth import auth_bp
app.register_blueprint(auth_bp)

反查时带蓝图前缀:url_for('auth.login')。子域名功能需要先配置 SERVER_NAME(如 example.com),再在蓝图上声明 subdomain。

SQLAlchemy ORM 细节​

db.session.add(user) # 只是加入会话(事务),未写库
db.session.commit() # 此时才真正落库

两个高频对比:

API区别
filter_by只支持等值:filter_by(name='tom')
filter支持表达式:filter(User.name.like('%t%'))、filter(User.id.in_([1,2]))
first无结果返回 None,不报错
one必须恰好一条,多条或零条都抛异常

first 适合"取不到也正常"的业务查询;one 适合"必须存在且唯一"的强约束场景,异常即 bug 信号。

create_all() 只建不改:表不存在会创建,表存在但缺新字段不会加列。线上改表结构走迁移工具 alembic / Flask-Migrate(flask db migrate 生成脚本 → flask db upgrade 执行),可审查、可回滚。

上下文与 session​

Flask 有两对上下文,把"请求级全局变量"做得像局部变量:

  • 应用上下文:current_app(当前应用实例)、g(一次请求内的临时存取,如数据库连接)。
  • 请求上下文:request(本次请求)、session(用户会话)。

Flask 的 session 是 client side:数据序列化后加密签名,整体存在浏览器 cookie 里(默认其内容 base64 可见、靠签名防篡改,敏感信息别放),服务端不存——这和 Django 服务端 session 形成对比。优点是服务端无状态、好水平扩展;缺点是 cookie 4KB 上限、用户清 cookie 即"登出"。

高频面试题​

问题答题要点
Flask 与 Django 的区别、怎么选?微框架 vs 全家桶;小服务/AI 接口用 Flask,复杂业务带后台用 Django
url_for 好在哪?函数名反查 URL,改路由不动调用方;自动转义、拼查询参数
filter_by 和 filter、first / one 的区别?filter_by 仅等值,filter 支持表达式;first 返回 None,one 强约束必须恰好一条
蓝图解决什么问题?应用模块化拆分,各蓝图独立注册路由/模板,url_for('蓝图.视图') 反查
Flask 的 session 存在哪?加密签名后整体存客户端 cookie(client side);服务端无状态但受 4KB 限制
create_all() 能改表吗?不能,只建不改;线上走 alembic / Flask-Migrate 迁移
请求上下文有哪些、g 是什么?request/session + current_app/g;g 是单次请求内的共享暂存区