第135集 Flask框架基础
1. Flask框架简介
Flask是一个轻量级的Python Web框架,以其简洁、灵活和可扩展的特性而闻名。它由Armin Ronacher于2010年创建,基于Werkzeug WSGI工具包和Jinja2模板引擎。
1.1 Flask的历史
- 2010年4月:Flask首次发布
- 2010年6月:发布Flask 0.1版本
- 2018年4月:发布Flask 1.0版本
- 2020年5月:发布Flask 1.1版本
- 2023年1月:发布Flask 2.3版本
1.2 Flask的特点
- 轻量级:核心功能简洁,只包含必要的组件
- 灵活性:允许开发者选择自己喜欢的扩展和工具
- 可扩展:拥有丰富的第三方扩展生态系统
- 简单易学:API设计直观,上手难度低
- 支持RESTful:适合构建RESTful API
- 内置开发服务器:方便开发和测试
- Jinja2模板引擎:强大的模板渲染能力
- Werkzeug WSGI工具包:提供了请求处理、路由等核心功能
1.3 Flask与其他框架的比较
| 特性 | Flask | Django | Bottle |
|---|---|---|---|
| 类型 | 微框架 | 全栈框架 | 微框架 |
| 灵活性 | 高 | 低 | 高 |
| 内置功能 | 少 | 多 | 少 |
| 学习曲线 | 平缓 | 陡峭 | 平缓 |
| 社区支持 | 大 | 极大 | 小 |
| 适合项目 | 小型到中型 | 大型 | 小型 |
2. Flask的安装
2.1 安装Flask
使用pip安装Flask非常简单:
# 安装最新版本
pip install flask
# 安装特定版本
pip install flask==2.3.32.2 验证安装
安装完成后,可以通过以下方式验证:
import flask
print(flask.__version__)
# 输出: 2.3.32.3 虚拟环境
推荐在虚拟环境中安装Flask,以避免依赖冲突:
# 创建虚拟环境
python -m venv venv
# 激活虚拟环境(Windows)
venv\Scripts\activate
# 激活虚拟环境(Linux/Mac)
source venv/bin/activate
# 安装Flask
pip install flask3. Flask第一个应用
3.1 创建基本结构
创建一个简单的Flask应用,只需要几行代码:
# app.py
from flask import Flask
# 创建Flask应用实例
app = Flask(__name__)
# 定义路由和视图函数
@app.route('/')
def hello_world():
return 'Hello, Flask!'
# 启动应用
if __name__ == '__main__':
app.run()3.2 运行应用
python app.py运行后,你会看到类似以下输出:
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)现在可以在浏览器中访问 http://127.0.0.1:5000/ ,看到"Hello, Flask!"的输出。
3.3 启用调试模式
调试模式下,Flask会自动重载代码变化,并提供详细的错误信息:
# 方式1:在app.run()中设置
app.run(debug=True)
# 方式2:通过环境变量设置
export FLASK_ENV=development # Linux/Mac
export FLASK_APP=app.py
flask run
# Windows
sets FLASK_ENV=development
sets FLASK_APP=app.py
flask run4. Flask应用的基本结构
一个典型的Flask应用结构如下:
myapp/
├── app.py # 主应用文件
├── templates/ # 模板文件目录
│ ├── index.html
│ └── about.html
├── static/ # 静态文件目录
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── script.js
│ └── images/
│ └── logo.png
├── venv/ # 虚拟环境
└── requirements.txt # 依赖列表4.1 主应用文件
主应用文件通常包含Flask应用实例的创建、路由定义和配置等。
4.2 模板目录
存放HTML模板文件,使用Jinja2模板引擎渲染。
4.3 静态目录
存放CSS、JavaScript、图片等静态资源文件。
4.4 依赖列表
使用pip freeze > requirements.txt命令生成,包含项目的所有依赖包。
5. Flask路由
路由是指将URL与视图函数关联起来的机制。
5.1 基本路由
使用@app.route()装饰器定义路由:
@app.route('/')
def index():
return '首页'
@app.route('/about')
def about():
return '关于我们'5.2 动态路由
可以在路由中使用变量,用尖括号包裹:
@app.route('/user/<username>')
def show_user_profile(username):
return f'用户 {username}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'文章 {post_id}'
@app.route('/path/<path:subpath>')
def show_subpath(subpath):
return f'子路径 {subpath}'5.3 支持的转换器
string:默认类型,接受任何不包含斜杠的文本int:接受正整数float:接受正浮点数path:类似string,但可以包含斜杠uuid:接受UUID字符串
5.4 HTTP方法
默认情况下,路由只接受GET请求,可以通过methods参数指定允许的HTTP方法:
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# 处理登录表单提交
username = request.form['username']
password = request.form['password']
return f'登录用户: {username}'
else:
# 显示登录表单
return '显示登录表单'6. Flask请求处理
6.1 请求对象
Flask提供了request对象来访问请求数据:
from flask import request
@app.route('/login', methods=['POST'])
def login():
# 获取表单数据
username = request.form['username'] # POST请求表单数据
password = request.form['password']
# 获取查询参数
next_url = request.args.get('next') # GET请求查询参数
# 获取请求头
user_agent = request.headers.get('User-Agent')
# 获取JSON数据
if request.is_json:
data = request.get_json()
return f'登录用户: {username}'6.2 响应对象
可以返回不同类型的响应:
from flask import Response, jsonify
# 返回字符串
@app.route('/')
def index():
return 'Hello World'
# 返回元组 (响应内容, 状态码, 响应头)
@app.route('/not_found')
def not_found():
return 'Not Found', 404
# 返回Response对象
@app.route('/custom_response')
def custom_response():
response = Response('Custom Response', status=200, mimetype='text/plain')
response.headers['X-Custom-Header'] = 'value'
return response
# 返回JSON
@app.route('/api/data')
def api_data():
data = {'name': '张三', 'age': 20}
return jsonify(data)6.3 Cookie和Session
Cookie
from flask import make_response
@app.route('/set_cookie')
def set_cookie():
response = make_response('设置Cookie')
response.set_cookie('username', '张三', max_age=3600) # 1小时
return response
@app.route('/get_cookie')
def get_cookie():
username = request.cookies.get('username')
return f'Cookie中的用户名: {username}'Session
Session使用密钥签名,需要设置SECRET_KEY:
app.secret_key = 'your-secret-key'
from flask import session
@app.route('/set_session')
def set_session():
session['username'] = '张三'
return '设置Session'
@app.route('/get_session')
def get_session():
username = session.get('username')
return f'Session中的用户名: {username}'
@app.route('/clear_session')
def clear_session():
session.pop('username', None)
return '清除Session'7. Flask模板
7.1 渲染模板
使用render_template()函数渲染模板:
from flask import render_template
@app.route('/')
def index():
return render_template('index.html')
@app.route('/user/<username>')
def show_user(username):
return render_template('user.html', name=username, age=20)7.2 模板变量
在模板中使用{{ 变量名 }}来输出变量:
<!DOCTYPE html>
<html>
<head>
<title>用户信息</title>
</head>
<body>
<h1>欢迎, {{ name }}!</h1>
<p>年龄: {{ age }}</p>
</body>
</html>7.3 模板控制结构
条件语句
{% if age >= 18 %}
<p>成年人</p>
{% elif age >= 13 %}
<p>青少年</p>
{% else %}
<p>儿童</p>
{% endif %}循环语句
<ul>
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% endfor %}
</ul>宏
{% macro input(name, value='', type='text') %}
<input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}
{{ input('username') }}
{{ input('password', type='password') }}继承
<!-- base.html -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}默认标题{% endblock %}</title>
</head>
<body>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
<!-- index.html -->
{% extends "base.html" %}
{% block title %}首页{% endblock %}
{% block content %}
<h1>首页内容</h1>
{% endblock %}7.4 过滤器
{{ name|capitalize }} <!-- 首字母大写 -->
{{ message|safe }} <!-- 安全输出 -->
{{ text|truncate(50) }} <!-- 截断文本 -->
{{ price|format("%.2f") }} <!-- 格式化数字 -->
{{ list|join(", ") }} <!-- 连接列表 -->8. Flask静态文件
8.1 引用静态文件
使用url_for()函数生成静态文件的URL:
<!-- 引用CSS -->
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<!-- 引用JavaScript -->
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
<!-- 引用图片 -->
<img src="{{ url_for('static', filename='images/logo.png') }}" alt="Logo">8.2 自定义静态目录
可以自定义静态目录的位置:
app = Flask(__name__, static_folder='assets')9. Flask扩展
Flask拥有丰富的第三方扩展,以下是一些常用的扩展:
9.1 数据库扩展
- Flask-SQLAlchemy:SQLAlchemy的Flask集成,用于数据库操作
- Flask-Migrate:数据库迁移工具
- Flask-MongoEngine:MongoDB的Flask集成
9.2 用户认证
- Flask-Login:用户会话管理
- Flask-Security:用户认证和授权
- Flask-JWT-Extended:JWT认证
9.3 表单处理
- Flask-WTF:WTForms的Flask集成,用于表单处理
9.4 API开发
- Flask-RESTful:用于构建RESTful API
- Flask-RESTPlus:提供API文档的RESTful扩展
9.5 缓存
- Flask-Cache:缓存支持
9.6 邮件
- Flask-Mail:邮件发送功能
10. Flask配置
10.1 配置方法
直接设置
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'your-secret-key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'使用配置文件
# config.py
class Config:
DEBUG = False
SECRET_KEY = 'your-secret-key'
class DevelopmentConfig(Config):
DEBUG = True
class ProductionConfig(Config):
SECRET_KEY = 'production-secret-key'
# app.py
app = Flask(__name__)
app.config.from_object('config.DevelopmentConfig')使用环境变量
import os
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'default-key')10.2 常用配置项
DEBUG:是否启用调试模式SECRET_KEY:用于加密会话数据TESTING:是否启用测试模式JSON_SORT_KEYS:是否对JSON响应中的键进行排序SERVER_NAME:服务器名称PERMANENT_SESSION_LIFETIME:会话过期时间
11. Flask错误处理
11.1 自定义错误页面
使用@app.errorhandler()装饰器定义错误处理函数:
@app.errorhandler(404)
def page_not_found(error):
return render_template('404.html'), 404
@app.errorhandler(500)
def internal_server_error(error):
return render_template('500.html'), 500
@app.errorhandler(403)
def forbidden(error):
return render_template('403.html'), 40311.2 异常处理
可以捕获特定的异常:
try:
# 可能出错的代码
except Exception as e:
# 处理异常
return render_template('error.html', error=e), 50012. Flask最佳实践
12.1 项目结构
使用蓝图组织代码,提高代码的可维护性:
myapp/
├── app/
│ ├── __init__.py
│ ├── main/
│ │ ├── __init__.py
│ │ ├── routes.py
│ │ └── forms.py
│ ├── auth/
│ │ ├── __init__.py
│ │ ├── routes.py
│ │ └── forms.py
│ ├── models.py
│ ├── config.py
│ └── utils.py
├── migrations/
├── tests/
├── venv/
├── run.py
└── requirements.txt12.2 使用蓝图
蓝图允许将应用分解为多个模块:
# app/main/__init__.py
from flask import Blueprint
main = Blueprint('main', __name__)
from . import routes
# app/auth/__init__.py
from flask import Blueprint
auth = Blueprint('auth', __name__)
from . import routes
# app/__init__.py
from flask import Flask
from .main import main as main_blueprint
from .auth import auth as auth_blueprint
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
app.register_blueprint(main_blueprint, url_prefix='/')
app.register_blueprint(auth_blueprint, url_prefix='/auth')
return app12.3 安全性
- 不要在生产环境中启用调试模式
- 使用强密码作为SECRET_KEY
- 对用户输入进行验证和过滤
- 使用HTTPS协议
- 避免SQL注入
- 正确处理错误信息,不要泄露敏感信息
12.4 性能优化
- 使用缓存减少数据库查询
- 使用异步处理耗时操作
- 优化模板渲染
- 使用CDN加速静态文件
- 启用gzip压缩
13. 总结
Flask是一个轻量级、灵活、可扩展的Python Web框架,适合构建各种规模的Web应用。它的核心特点是简洁和灵活,允许开发者根据自己的需求选择合适的工具和扩展。
本集主要介绍了Flask的基本概念、安装、第一个应用、路由、请求处理、模板、静态文件、配置和最佳实践等内容。通过学习这些基础知识,你已经可以开始使用Flask构建简单的Web应用了。
在后续的学习中,我们将深入学习Flask的路由与视图、模板、表单处理、数据库集成等高级功能,以及如何使用Flask构建完整的Web应用。