本文目录导读:

- 安装 Flask
- 基础案例:Hello World
- URL路由和参数传递
- 处理GET和POST请求
- 使用模板(HTML渲染)
- RESTful API 案例
- 文件上传案例
- 数据库整合(SQLite)
- 使用蓝图(Blueprint)组织代码
- 运行配置
- 实用技巧
我来详细介绍一下 Flask 框架的基本使用方法,包含几个典型案例。
安装 Flask
pip install flask
基础案例:Hello World
# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True)
运行:
python app.py # 访问 http://localhost:5000
URL路由和参数传递
from flask import Flask
app = Flask(__name__)
# 基本路由
@app.route('/')
def index():
return '首页'
# 带参数的路由
@app.route('/user/<username>')
def show_user(username):
return f'用户: {username}'
# 指定参数类型
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'文章ID: {post_id}'
# 多参数
@app.route('/user/<username>/<int:age>')
def user_info(username, age):
return f'用户: {username}, 年龄: {age}'
if __name__ == '__main__':
app.run(debug=True)
处理GET和POST请求
from flask import Flask, request, jsonify
app = Flask(__name__)
# GET请求
@app.route('/api/data', methods=['GET'])
def get_data():
# 获取查询参数
name = request.args.get('name', '默认名称')
return jsonify({
'message': f'Hello {name}',
'method': 'GET'
})
# POST请求
@app.route('/api/data', methods=['POST'])
def post_data():
# 获取JSON数据
data = request.get_json()
if data:
name = data.get('name', '匿名')
return jsonify({
'message': f'收到POST数据: {name}',
'method': 'POST'
})
return jsonify({'error': '没有数据'}), 400
# 表单数据
@app.route('/login', methods=['POST'])
def login():
username = request.form.get('username')
password = request.form.get('password')
return jsonify({
'username': username,
'password': '***' # 实际项目中不要返回密码
})
if __name__ == '__main__':
app.run(debug=True)
使用模板(HTML渲染)
# app.py
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html', title='首页')
@app.route('/user/<name>')
def user(name):
return render_template('user.html',
username=name,
age=25,
skills=['Python', 'Flask', 'JavaScript'])
@app.route('/search')
def search():
query = request.args.get('q', '')
return render_template('search.html', query=query)
if __name__ == '__main__':
app.run(debug=True)
创建 templates/index.html:
<!DOCTYPE html>
<html>
<head>{{ title }}</title>
</head>
<body>
<h1>欢迎来到我的网站</h1>
<p>这是首页内容</p>
<!-- 表单示例 -->
<form action="/search" method="GET">
<input type="text" name="q" placeholder="搜索...">
<button type="submit">搜索</button>
</form>
</body>
</html>
创建 templates/user.html:
<!DOCTYPE html>
<html>
<head>{{ username }}的个人页面</title>
</head>
<body>
<h1>{{ username }}的个人信息</h1>
<p>年龄: {{ age }}</p>
<h2>技能列表</h2>
<ul>
{% for skill in skills %}
<li>{{ skill }}</li>
{% endfor %}
</ul>
<!-- 条件判断 -->
{% if age >= 18 %}
<p>已成年</p>
{% else %}
<p>未成年</p>
{% endif %}
</body>
</html>
RESTful API 案例
from flask import Flask, request, jsonify
app = Flask(__name__)
# 模拟数据库
books = [
{'id': 1, 'title': 'Python编程', 'author': '张三'},
{'id': 2, 'title': 'Flask实战', 'author': '李四'}
]
# 获取所有书籍
@app.route('/api/books', methods=['GET'])
def get_books():
return jsonify(books)
# 获取单本书籍
@app.route('/api/books/<int:book_id>', methods=['GET'])
def get_book(book_id):
book = next((b for b in books if b['id'] == book_id), None)
if book:
return jsonify(book)
return jsonify({'error': '书籍不存在'}), 404
# 添加书籍
@app.route('/api/books', methods=['POST'])
def add_book():
data = request.get_json()
if not data or 'title' not in data:
return jsonify({'error': '请提供书名'}), 400
new_book = {
'id': len(books) + 1,
'title': data['title'],
'author': data.get('author', '未知')
}
books.append(new_book)
return jsonify(new_book), 201
# 更新书籍
@app.route('/api/books/<int:book_id>', methods=['PUT'])
def update_book(book_id):
book = next((b for b in books if b['id'] == book_id), None)
if not book:
return jsonify({'error': '书籍不存在'}), 404
data = request.get_json()
book.update(data)
return jsonify(book)
# 删除书籍
@app.route('/api/books/<int:book_id>', methods=['DELETE'])
def delete_book(book_id):
global books
books = [b for b in books if b['id'] != book_id]
return jsonify({'message': '删除成功'})
if __name__ == '__main__':
app.run(debug=True)
文件上传案例
from flask import Flask, request, jsonify, render_template
import os
from werkzeug.utils import secure_filename
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB限制
# 确保上传目录存在
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
@app.route('/upload')
def upload_page():
return render_template('upload.html')
@app.route('/api/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return jsonify({'error': '没有文件'}), 400
file = request.files['file']
if file.filename == '':
return jsonify({'error': '未选择文件'}), 400
if file:
# 安全文件名
filename = secure_filename(file.filename)
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
# 保存文件
file.save(filepath)
return jsonify({
'message': '上传成功',
'filename': filename,
'filepath': filepath
})
if __name__ == '__main__':
app.run(debug=True)
创建 templates/upload.html:
<!DOCTYPE html>
<html>
<head>文件上传</title>
</head>
<body>
<h1>文件上传</h1>
<form action="/api/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file" required>
<button type="submit">上传</button>
</form>
</body>
</html>
数据库整合(SQLite)
from flask import Flask, request, jsonify
import sqlite3
from contextlib import closing
app = Flask(__name__)
def init_db():
with closing(sqlite3.connect('database.db')) as conn:
cur = conn.cursor()
cur.execute('''CREATE TABLE IF NOT EXISTS users
(id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL)''')
conn.commit()
@app.route('/api/users', methods=['GET'])
def get_users():
conn = sqlite3.connect('database.db')
cur = conn.cursor()
cur.execute('SELECT * FROM users')
users = [{'id': row[0], 'name': row[1], 'email': row[2]}
for row in cur.fetchall()]
conn.close()
return jsonify(users)
@app.route('/api/users', methods=['POST'])
def add_user():
data = request.get_json()
try:
conn = sqlite3.connect('database.db')
cur = conn.cursor()
cur.execute('INSERT INTO users (name, email) VALUES (?, ?)',
(data['name'], data['email']))
conn.commit()
user_id = cur.lastrowid
conn.close()
return jsonify({'id': user_id, **data}), 201
except sqlite3.IntegrityError:
return jsonify({'error': '邮箱已存在'}), 400
# 初始化数据库
init_db()
if __name__ == '__main__':
app.run(debug=True)
使用蓝图(Blueprint)组织代码
# app.py
from flask import Flask
from blueprints.user import user_bp
from blueprints.admin import admin_bp
app = Flask(__name__)
# 注册蓝图
app.register_blueprint(user_bp, url_prefix='/user')
app.register_blueprint(admin_bp, url_prefix='/admin')
if __name__ == '__main__':
app.run(debug=True)
# blueprints/user.py
from flask import Blueprint, jsonify
user_bp = Blueprint('user', __name__)
@user_bp.route('/list')
def user_list():
return jsonify({'users': ['张三', '李四', '王五']})
@user_bp.route('/profile/<int:user_id>')
def user_profile(user_id):
return jsonify({'user_id': user_id, 'name': f'用户{user_id}'})
# blueprints/admin.py
from flask import Blueprint, jsonify
admin_bp = Blueprint('admin', __name__)
@admin_bp.route('/dashboard')
def dashboard():
return jsonify({'status': 'admin dashboard'})
@admin_bp.route('/settings')
def settings():
return jsonify({'setting': 'admin settings'})
运行配置
# config.py
class Config:
DEBUG = False
SECRET_KEY = 'your-secret-key'
DATABASE_URI = 'sqlite:///app.db'
class DevelopmentConfig(Config):
DEBUG = True
class ProductionConfig(Config):
DEBUG = False
DATABASE_URI = 'mysql://user:password@localhost/db'
# app.py
from flask import Flask
app = Flask(__name__)
app.config.from_object('config.DevelopmentConfig')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
实用技巧
- 调试模式:
app.run(debug=True)自动重载代码 - 环境变量:
export FLASK_ENV=development - 端口设置:
app.run(port=8080) - 跨域支持:安装
flask-cors - 测试客户端:
app.test_client()
这些案例覆盖了 Flask 的主要功能,从简单到复杂,你可以根据实际需求选择使用。