Flask 基础教程
Flask 是一个轻量级的 Python Web 框架,旨在简化 Web 应用的开发过程。下面是 Flask 的基础教程,包括核心概念和示例代码。
1. Flask 简介
Flask 是一个 WSGI 应用程序框架,设计上十分灵活,允许开发者选择最适合的组件和库。它支持多种扩展,使其适用于从简单的 Web 应用到复杂的应用程序。
核心特点:
- 轻量级:核心库很小,扩展可以添加各种功能。
- 灵活性:允许开发者自由选择组件和库。
- 易于上手:提供了简单易用的 API 和强大的文档支持。
2. 安装 Flask
使用 pip
安装 Flask:
pip install flask
3. 创建第一个 Flask 应用
示例代码:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True)
详解:
- Flask 实例:
app = Flask(__name__)
创建 Flask 应用实例。 - 路由:使用
@app.route('/')
装饰器定义根路径的处理函数。 - 运行应用:
app.run(debug=True)
启动开发服务器,并启用调试模式。
4. 路由和视图函数
示例代码:
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/')
def index():
return 'Welcome to Flask!'
@app.route('/hello/<name>')
def hello(name):
return f'Hello, {name}!'
@app.route('/json', methods=['POST'])
def json_example():
data = request.json
return jsonify(data)
if __name__ == '__main__':
app.run(debug=True)
详解:
- 动态路由:
/hello/<name>
,在 URL 中定义动态部分。 - 请求处理:
request
对象用于获取请求数据。 - JSON 响应:
jsonify
用于返回 JSON 格式的数据。
5. 请求和响应
示例代码:
from flask import Flask, request, make_response
app = Flask(__name__)
@app.route('/greet', methods=['POST'])
def greet():
name = request.form.get('name', 'Guest')
response = make_response(f'Hello, {name}!')
response.headers['Custom-Header'] = 'Value'
return response
if __name__ == '__main__':
app.run(debug=True)
详解:
- 请求数据:
request.form.get('name')
获取表单数据。 - 自定义响应:
make_response
创建响应对象,并设置自定义头部。
6. 模板渲染
Flask 使用 Jinja2 模板引擎来渲染 HTML 模板。
示例代码:
-
创建模板文件 (
templates/hello.html
):html <!DOCTYPE html> <html> <head> <title>Hello</title> </head> <body> <h1>Hello, {{ name }}!</h1> </body> </html>
-
Flask 应用:
```python from flask import Flask, render_template
app = Flask(name)
@app.route('/hello/
') def hello(name): return render_template('hello.html', name=name) if name == 'main': app.run(debug=True) ```
详解:
render_template
:用于渲染 HTML 模板,并传递数据。- 模板变量:
{{ name }}
用于在模板中插入数据。
7. 表单处理
示例代码:
-
HTML 表单 (
templates/form.html
):html <!DOCTYPE html> <html> <head> <title>Form</title> </head> <body> <form method="POST" action="/submit"> <label for="name">Name:</label> <input type="text" id="name" name="name"> <input type="submit" value="Submit"> </form> </body> </html>
-
Flask 应用:
```python from flask import Flask, request, render_template
app = Flask(name)
@app.route('/form') def form(): return render_template('form.html')
@app.route('/submit', methods=['POST']) def submit(): name = request.form['name'] return f'Submitted name: {name}'
if name == 'main': app.run(debug=True) ```
详解:
request.form
:用于获取表单提交的数据。- 表单提交:表单数据通过 POST 方法提交到
/submit
路由。
8. 数据库集成(使用 SQLite 和 SQLAlchemy)
安装 SQLAlchemy:
pip install sqlalchemy flask_sqlalchemy
示例代码:
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)
class Item(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
@app.before_first_request
def create_tables():
db.create_all()
@app.route('/items', methods=['POST'])
def create_item():
data = request.json
new_item = Item(name=data['name'])
db.session.add(new_item)
db.session.commit()
return jsonify({"id": new_item.id, "name": new_item.name})
@app.route('/items', methods=['GET'])
def get_items():
items = Item.query.all()
return jsonify([{"id": item.id, "name": item.name} for item in items])
if __name__ == '__main__':
app.run(debug=True)
详解:
- SQLAlchemy:用于与数据库交互的 ORM 工具。
db.Model
:定义数据模型类。db.create_all()
:创建数据库表。
9. 错误处理
示例代码:
from flask import Flask, jsonify
app = Flask(__name__)
@app.errorhandler(404)
def not_found(error):
return jsonify({"error": "Not Found"}), 404
@app.route('/cause_error')
def cause_error():
abort(404)
if __name__ == '__main__':
app.run(debug=True)
详解:
@app.errorhandler
:用于定义错误处理器。abort(404)
:触发错误处理器。
10. 测试 Flask 应用
示例代码:
from flask import Flask, jsonify
import unittest
app = Flask(__name__)
@app.route('/')
def index():
return jsonify(message="Hello, World!")
class FlaskTestCase(unittest.TestCase):
def setUp(self):
app.config['TESTING'] = True
self.app = app.test_client()
def test_index(self):
response = self.app.get('/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json, {"message": "Hello, World!"})
if __name__ == '__main__':
unittest.main()
详解:
unittest
:Python 的标准测试框架。app.test_client()
:创建测试客户端,用于模拟请求。
11. Flask 的中间件
中间件是指在处理请求和响应过程中插入的代码,它可以修改请求、响应或其他处理行为。
示例:自定义中间件
示例代码:
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.before_request
def before_request():
print("Before request is called")
if request.method != "GET":
return jsonify({"message": "Only GET requests are allowed"}), 403
@app.after_request
def after_request(response):
print("After request is called")
response.headers["X-Custom-Header"] = "CustomHeaderValue"
return response
@app.route('/test')
def test():
return jsonify({"message": "This is a test"})
if __name__ == '__main__':
app.run(debug=True)
详解:
@app.before_request
:在每个请求前调用,可以用于验证或记录日志。@app.after_request
:在请求处理后调用,可以修改响应头或处理后续操作。
12. Flask 的 Cookie 和会话管理
Flask 提供了对 Cookie 和会话的内置支持,可以用来管理用户的登录状态等信息。
使用 Cookie
示例代码:
from flask import Flask, request, make_response
app = Flask(__name__)
@app.route('/set-cookie')
def set_cookie():
response = make_response("Cookie has been set")
response.set_cookie('username', 'john_doe')
return response
@app.route('/get-cookie')
def get_cookie():
username = request.cookies.get('username')
return f'Username from cookie is {username}'
if __name__ == '__main__':
app.run(debug=True)
详解:
set_cookie()
:用于设置 Cookie。request.cookies.get()
:用于获取请求中的 Cookie。
使用会话
Flask 会话存储在客户端(通常是浏览器的 Cookie 中),但它经过签名,确保不会被篡改。
示例代码:
from flask import Flask, session, redirect, url_for, request
app = Flask(__name__)
app.secret_key = 'supersecretkey'
@app.route('/')
def index():
if 'username' in session:
return f'Logged in as {session["username"]}'
return 'You are not logged in'
@app.route('/login', methods=['POST'])
def login():
session['username'] = request.form['username']
return redirect(url_for('index'))
@app.route('/logout')
def logout():
session.pop('username', None)
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)
详解:
session
:用于在客户端存储会话数据。session.pop()
:用于删除会话中的数据。
13. Flask 扩展:Flask-RESTful
Flask-RESTful
是一个用于快速构建 REST API 的 Flask 扩展,它简化了 API 的开发过程。
安装 Flask-RESTful
pip install flask-restful
使用示例
示例代码:
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}
api.add_resource(HelloWorld, '/')
if __name__ == '__main__':
app.run(debug=True)
详解:
Resource
:每个资源表示 API 的一个端点。add_resource
:将资源与 URL 关联,处理相应的请求。
14. Flask 的文件上传
Flask 支持处理文件上传,并允许开发者设置上传文件的存储路径。
示例:文件上传处理
示例代码:
from flask import Flask, request
app = Flask(__name__)
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return 'No file part'
file = request.files['file']
if file.filename == '':
return 'No selected file'
file.save(f'./uploads/{file.filename}')
return 'File uploaded successfully'
if __name__ == '__main__':
app.run(debug=True)
详解:
request.files
:用于处理上传的文件。file.save()
:将上传的文件保存到指定的路径。
15. Flask 的静态文件和模板
Flask 提供了内置的方式来处理静态文件(如 CSS、JavaScript)和模板渲染。
处理静态文件
静态文件(如 CSS
或 JavaScript
)应该放置在 static/
目录下,Flask 自动提供对该目录中文件的访问。
示例:引用静态文件
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<h1>Welcome to Flask</h1>
</body>
</html>
详解:
url_for('static', filename='style.css')
:生成静态文件的 URL。
模板继承
Flask 支持模板继承,可以使多个页面共享布局。
-
基础模板 (
templates/base.html
):html <!DOCTYPE html> <html> <head> <title>{% block title %}Flask App{% endblock %}</title> </head> <body> <header> <h1>Welcome to My Flask App</h1> </header> <div> {% block content %}{% endblock %} </div> </body> </html>
-
继承模板 (
templates/index.html
):```html {% extends 'base.html' %}
{% block title %}Home Page{% endblock %}
{% block content %}
This is the home page.
{% endblock %} ```
16. Flask 的蓝图(Blueprint)
Blueprint
是 Flask 中的一种模块化设计工具,可以帮助我们将应用程序划分为多个模块,便于维护和扩展。
示例:使用蓝图
-
定义蓝图文件 (
app/routes.py
):```python from flask import Blueprint
bp = Blueprint('main', name)
@bp.route('/') def index(): return "This is the main page" ```
-
注册蓝图 (
app.py
):```python from flask import Flask from app.routes import bp
app = Flask(name) app.register_blueprint(bp)
if name == 'main': app.run(debug=True) ```
详解:
Blueprint
:用于模块化组织路由和处理函数。app.register_blueprint()
:注册蓝图到主应用。
17. 部署 Flask 应用
Flask 应用可以部署在多个平台上,如 WSGI 服务器、Docker 等。
部署在 Gunicorn 上
-
安装 Gunicorn:
bash pip install gunicorn
-
启动应用:
bash gunicorn -w 4 app:app
详解:
-w 4
:指定使用 4 个工作进程。app:app
:app.py
文件中的 Flask 实例名为app
。
使用 Docker 部署
-
创建
Dockerfile
:```Dockerfile FROM python:3.9-slim
WORKDIR /app COPY . /app
RUN pip install -r requirements.txt
CMD ["gunicorn", "-w", "4", "app:app"] ```
-
构建并运行 Docker 镜像:
bash docker build -t flask-app . docker run -p 8000:8000 flask-app
详解:
- Dockerfile:定义了应用的依赖、工作目录和启动命令。
docker build
和docker run
:用于构建并运行 Docker 容器。