跳转至

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 模板。

示例代码:

  1. 创建模板文件 (templates/hello.html):

    html <!DOCTYPE html> <html> <head> <title>Hello</title> </head> <body> <h1>Hello, {{ name }}!</h1> </body> </html>

  2. 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. 表单处理

示例代码:

  1. 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>

  2. 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:在请求处理后调用,可以修改响应头或处理后续操作。

Flask 提供了对 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)和模板渲染。

处理静态文件

静态文件(如 CSSJavaScript)应该放置在 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 支持模板继承,可以使多个页面共享布局。

  1. 基础模板 (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>

  2. 继承模板 (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 中的一种模块化设计工具,可以帮助我们将应用程序划分为多个模块,便于维护和扩展。

示例:使用蓝图

  1. 定义蓝图文件 (app/routes.py):

    ```python from flask import Blueprint

    bp = Blueprint('main', name)

    @bp.route('/') def index(): return "This is the main page" ```

  2. 注册蓝图 (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 上

  1. 安装 Gunicorn:

    bash pip install gunicorn

  2. 启动应用:

    bash gunicorn -w 4 app:app

详解:

  • -w 4:指定使用 4 个工作进程。
  • app:appapp.py 文件中的 Flask 实例名为 app

使用 Docker 部署

  1. 创建 Dockerfile

    ```Dockerfile FROM python:3.9-slim

    WORKDIR /app COPY . /app

    RUN pip install -r requirements.txt

    CMD ["gunicorn", "-w", "4", "app:app"] ```

  2. 构建并运行 Docker 镜像:

    bash docker build -t flask-app . docker run -p 8000:8000 flask-app

详解:

  • Dockerfile:定义了应用的依赖、工作目录和启动命令。
  • docker builddocker run:用于构建并运行 Docker 容器。