📘 课程目标
- 了解 Flask 框架及特点
- 完成开发环境配置
- 创建并运行第一个 Flask 应用
- 掌握基本路由和请求处理
- 理解Flask项目结构和最佳实践
🧠 一、什么是 Flask?
Flask 是一个基于 Python 的轻量级 Web 框架,适合快速构建 Web 应用和 API。
🔹 Flask 的特点:
- 轻量灵活:核心功能简洁,可扩展性强
- 开发友好:内置开发服务器与调试器
- 模板系统:内置路由系统与模板引擎 Jinja2
- 丰富生态:插件丰富(如 Flask-Login、Flask-Migrate、Flask-SQLAlchemy)
- RESTful 支持:天然支持 RESTful API 开发
🆚 Flask vs Django:
特点 | Flask | Django |
---|---|---|
学习曲线 | 平缓 | 陡峭 |
灵活性 | 高 | 中等 |
内置功能 | 少(需插件) | 多(开箱即用) |
适用场景 | 小到中型项目、API | 大型复杂项目 |
⚙️ 二、环境配置
✅ 安装步骤:
- 创建项目目录:
bash
mkdir flask_project
cd flask_project
- 创建虚拟环境(推荐):
bash
# 创建虚拟环境
python -m venv venv
# 激活虚拟环境
source venv/bin/activate # Mac/Linux
venv\Scripts\activate.bat # Windows(CMD)
venv\Scripts\Activate.ps1 # Windows(PowerShell)
- 安装 Flask:
bash
pip install flask
- 验证安装:
bash
python -m flask --version
🛠️ 推荐的开发工具:
- 代码编辑器:VS Code、PyCharm
- 版本控制:Git
- API 测试:Postman、curl
- 数据库管理:SQLite Browser
🚀 三、第一个 Flask 应用(Hello Flask)
📁 项目结构(推荐):
flask_project/
├── venv/ # 虚拟环境
├── app.py # 主应用文件
├── requirements.txt # 依赖列表
└── README.md # 项目说明
💻 基础应用代码:
python
# app.py
from flask import Flask
# 创建 Flask 应用实例
app = Flask(__name__)
# 基础路由
@app.route('/')
def index():
return "<h1>Hello, Flask!</h1>"
# 带参数的路由
@app.route('/user/<name>')
def user(name):
return f"<h1>Hello, {name}!</h1>"
# 指定HTTP方法
@app.route('/about', methods=['GET'])
def about():
return "<h1>这是关于页面</h1>"
if __name__ == '__main__':
app.run(debug=True, host='127.0.0.1', port=5000)
✅ 运行命令:
bash
python app.py
默认运行在 http://127.0.0.1:5000
📌 四、Flask 应用详解
🔧 核心组件说明:
Flask(__name__)
:创建应用实例,__name__
帮助Flask定位资源@app.route('/')
:装饰器定义URL路由规则debug=True
:开启调试模式,代码修改自动重载host
和port
:指定服务器地址和端口
🛣️ 路由详解:
python
# 1. 基础路由
@app.route('/')
def index():
return "首页"
# 2. 动态路由
@app.route('/user/<username>')
def show_user(username):
return f"用户:{username}"
# 3. 类型转换
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f"文章ID:{post_id}"
# 4. 多种HTTP方法
@app.route('/login', methods=['GET', 'POST'])
def login():
return "登录页面"
📱 支持的转换器类型:
string
:默认类型,接受任何不包含斜杠的文本int
:接受正整数float
:接受正浮点数path
:类似string,但接受斜杠uuid
:接受UUID字符串
🌟 五、进阶功能示例
📄 HTML 模板:
python
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/hello/<name>')
def hello(name):
return render_template('hello.html', name=name)
创建 templates/hello.html
:
html
<!DOCTYPE html>
<html>
<head>
<title>Hello {{ name }}</title>
</head>
<body>
<h1>Hello, {{ name }}!</h1>
</body>
</html>
📊 JSON API:
python
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/api/users')
def get_users():
users = [
{'id': 1, 'name': 'Alice'},
{'id': 2, 'name': 'Bob'}
]
return jsonify(users)
🎯 错误处理:
python
@app.errorhandler(404)
def not_found(error):
return '<h1>页面未找到</h1>', 404
@app.errorhandler(500)
def internal_error(error):
return '<h1>服务器内部错误</h1>', 500
🧪 六、实践练习
🎯 练习 1:基础路由
- 修改返回内容为
"你好,Flask!"
- 添加一个新的
/about
路由,返回"这是关于页面"
- 尝试使用不同端口运行应用:
app.run(port=8080)
🎯 练习 2:动态路由
创建以下路由:
/user/<name>
:显示用户信息/product/<int:id>
:显示产品详情(id必须为整数)/category/<path:category_path>
:显示分类路径
🎯 练习 3:简单API
创建一个简单的任务管理API:
GET /tasks
:返回所有任务的JSONGET /tasks/<int:task_id>
:返回特定任务的JSON
💡 七、最佳实践与小贴士
✅ 开发建议:
- 始终使用虚拟环境:避免包冲突
- 开启调试模式:方便开发调试
- 使用环境变量:存储敏感配置
- 遵循PEP 8:代码风格规范
- 及时处理错误:提供友好的错误页面
🔒 安全注意事项:
python
# 生产环境中关闭调试模式
if __name__ == '__main__':
app.run(debug=False)
# 使用环境变量存储密钥
import os
app.secret_key = os.environ.get('SECRET_KEY', 'dev-key')
📦 依赖管理:
bash
# 生成依赖文件
pip freeze > requirements.txt
# 安装依赖
pip install -r requirements.txt
🐛 八、常见问题解答
❓ Q1:ModuleNotFoundError: No module named 'flask'
A: 确保已激活虚拟环境并安装了Flask:
bash
source venv/bin/activate
pip install flask
❓ Q2:Address already in use 错误
A: 端口被占用,更换端口或停止占用该端口的进程:
python
app.run(port=8080) # 更换端口
❓ Q3:模板未找到错误
A: 确保在项目根目录创建了 templates
文件夹,并将HTML文件放入其中。
❓ Q4:静态文件(CSS/JS)无法加载
A: 将静态文件放在 static
文件夹中,并使用 url_for
引用:
html
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
✅ 完整示例代码
python
# app.py
from flask import Flask, render_template, jsonify
app = Flask(__name__)
# 基础路由
@app.route('/')
def index():
return "<h1>欢迎来到 Flask 学习!</h1>"
# 动态路由
@app.route('/user/<name>')
def user(name):
return f"<h1>Hello, {name}!</h1>"
# 关于页面
@app.route('/about')
def about():
return "<h1>这是关于页面</h1>"
# API示例
@app.route('/api/info')
def api_info():
return jsonify({
'name': 'Flask学习应用',
'version': '1.0',
'author': '学员'
})
# 错误处理
@app.errorhandler(404)
def not_found(error):
return '<h1>404 - 页面未找到</h1>', 404
if __name__ == '__main__':
app.run(debug=True, host='127.0.0.1', port=5000)
📚 下节课预告
下节课我们将学习:
- Flask 模板系统(Jinja2)
- 表单处理与验证
- 静态文件管理
- 会话管理
🎓 课后作业
- 完成所有练习题
- 创建一个个人简介页面,包含姓名、专业、兴趣爱好
- 实现一个简单的计算器API(加、减、乘、除)
- 阅读Flask官方文档的快速入门部分
提交要求:将代码上传到个人GitHub仓库,并发送链接。
📝 练习题答案
🎯 练习 1 答案:基础路由
python
# practice1.py
from flask import Flask
app = Flask(__name__)
# 1. 修改返回内容为中文
@app.route('/')
def index():
return "<h1>欢迎来到 Flask 学习! </h1>"
# 2. 添加关于页面路由
@app.route('/about')
def about():
return "这是关于页面"
if __name__ == '__main__':
# 3. 使用不同端口运行
app.run(debug=True, port=8080)
🎯 练习 2 答案:动态路由
python
# practice2.py
from flask import Flask
app = Flask(__name__)
# 显示用户信息
@app.route('/user/<name>')
def show_user(name):
return f"""
<h1>用户信息</h1>
<p>用户名:{name}</p>
<p>欢迎访问我们的网站!</p>
"""
# 显示产品详情(id必须为整数)
@app.route('/product/<int:id>')
def show_product(id):
return f"""
<h1>产品详情</h1>
<p>产品ID:{id}</p>
<p>产品类型:数字产品</p>
"""
# 显示分类路径
@app.route('/category/<path:category_path>')
def show_category(category_path):
return f"""
<h1>产品分类</h1>
<p>分类路径:{category_path}</p>
<p>您正在浏览:{category_path.replace('/', ' > ')}</p>
"""
if __name__ == '__main__':
app.run(debug=True)
🎯 练习 3 答案:简单API
python
# practice3.py
from flask import Flask, jsonify
app = Flask(__name__)
# 模拟任务数据
tasks = [
{"id": 1, "title": "学习Flask基础", "completed": False, "priority": "high"},
{"id": 2, "title": "完成练习题", "completed": False, "priority": "medium"},
{"id": 3, "title": "准备下节课", "completed": True, "priority": "low"}
]
# 获取所有任务
@app.route('/tasks')
def get_all_tasks():
return jsonify({
"success": True,
"count": len(tasks),
"tasks": tasks
})
# 获取特定任务
@app.route('/tasks/<int:task_id>')
def get_task(task_id):
# 查找任务
task = next((t for t in tasks if t["id"] == task_id), None)
if task:
return jsonify({
"success": True,
"task": task
})
else:
return jsonify({
"success": False,
"message": f"任务 {task_id} 未找到"
}), 404
if __name__ == '__main__':
app.run(debug=True)
🎓 课后作业答案
📝 作业 1:个人简介页面
python
# assignment1.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return '''
<h1>欢迎访问我的个人网站</h1>
<nav>
<a href="/profile">个人简介</a> |
<a href="/skills">技能专长</a> |
<a href="/contact">联系方式</a>
</nav>
'''
@app.route('/profile')
def profile():
return '''
<h1>个人简介</h1>
<div style="font-family: Arial; line-height: 1.6; max-width: 600px;">
<h2>基本信息</h2>
<p><strong>姓名:</strong>张三</p>
<p><strong>专业:</strong>计算机科学与技术</p>
<p><strong>年级:</strong>大三</p>
<h2>兴趣爱好</h2>
<ul>
<li>🖥️ 编程开发</li>
<li>📚 阅读技术书籍</li>
<li>🎮 游戏开发</li>
<li>🏃♂️ 跑步健身</li>
</ul>
<h2>学习目标</h2>
<p>希望通过学习Flask框架,能够开发出实用的Web应用,为将来的职业发展打下坚实基础。</p>
<a href="/">返回首页</a>
</div>
'''
@app.route('/skills')
def skills():
return '''
<h1>技能专长</h1>
<div style="font-family: Arial; line-height: 1.6;">
<h2>编程语言</h2>
<ul>
<li>Python ⭐⭐⭐⭐</li>
<li>JavaScript ⭐⭐⭐</li>
<li>Java ⭐⭐⭐</li>
<li>HTML/CSS ⭐⭐⭐⭐</li>
</ul>
<h2>框架技术</h2>
<ul>
<li>Flask (学习中)</li>
<li>Vue.js</li>
<li>Bootstrap</li>
</ul>
<a href="/">返回首页</a>
</div>
'''
@app.route('/contact')
def contact():
return '''
<h1>联系方式</h1>
<div style="font-family: Arial; line-height: 1.6;">
<p>📧 邮箱:zhangsan@example.com</p>
<p>📱 电话:138-0000-0000</p>
<p>🔗 GitHub:github.com/zhangsan</p>
<p>🏫 学校:XX大学计算机学院</p>
<a href="/">返回首页</a>
</div>
'''
if __name__ == '__main__':
app.run(debug=True)
🧮 作业 2:计算器API
python
# assignment2.py
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route('/')
def index():
return '''
<h1>Flask 计算器 API</h1>
<h2>API 使用说明</h2>
<div style="font-family: monospace; background: #f5f5f5; padding: 20px;">
<p><strong>加法:</strong> GET /add?a=10&b=5</p>
<p><strong>减法:</strong> GET /subtract?a=10&b=5</p>
<p><strong>乘法:</strong> GET /multiply?a=10&b=5</p>
<p><strong>除法:</strong> GET /divide?a=10&b=5</p>
<p><strong>综合计算:</strong> POST /calculate</p>
</div>
<h2>在线测试</h2>
<p><a href="/add?a=10&b=5">测试加法: 10 + 5</a></p>
<p><a href="/subtract?a=10&b=3">测试减法: 10 - 3</a></p>
<p><a href="/multiply?a=6&b=7">测试乘法: 6 × 7</a></p>
<p><a href="/divide?a=20&b=4">测试除法: 20 ÷ 4</a></p>
'''
# 加法
@app.route('/add')
def add():
try:
a = float(request.args.get('a', 0))
b = float(request.args.get('b', 0))
result = a + b
return jsonify({
"operation": "addition",
"operands": {"a": a, "b": b},
"result": result,
"expression": f"{a} + {b} = {result}"
})
except ValueError:
return jsonify({"error": "请提供有效的数字参数"}), 400
# 减法
@app.route('/subtract')
def subtract():
try:
a = float(request.args.get('a', 0))
b = float(request.args.get('b', 0))
result = a - b
return jsonify({
"operation": "subtraction",
"operands": {"a": a, "b": b},
"result": result,
"expression": f"{a} - {b} = {result}"
})
except ValueError:
return jsonify({"error": "请提供有效的数字参数"}), 400
# 乘法
@app.route('/multiply')
def multiply():
try:
a = float(request.args.get('a', 0))
b = float(request.args.get('b', 0))
result = a * b
return jsonify({
"operation": "multiplication",
"operands": {"a": a, "b": b},
"result": result,
"expression": f"{a} × {b} = {result}"
})
except ValueError:
return jsonify({"error": "请提供有效的数字参数"}), 400
# 除法
@app.route('/divide')
def divide():
try:
a = float(request.args.get('a', 0))
b = float(request.args.get('b', 0))
if b == 0:
return jsonify({"error": "除数不能为零"}), 400
result = a / b
return jsonify({
"operation": "division",
"operands": {"a": a, "b": b},
"result": result,
"expression": f"{a} ÷ {b} = {result}"
})
except ValueError:
return jsonify({"error": "请提供有效的数字参数"}), 400
# 综合计算(支持POST请求)
@app.route('/calculate', methods=['POST'])
def calculate():
try:
data = request.get_json()
if not data:
return jsonify({"error": "请提供JSON格式的数据"}), 400
a = float(data.get('a', 0))
b = float(data.get('b', 0))
operation = data.get('operation', '').lower()
if operation == 'add':
result = a + b
symbol = '+'
elif operation == 'subtract':
result = a - b
symbol = '-'
elif operation == 'multiply':
result = a * b
symbol = '×'
elif operation == 'divide':
if b == 0:
return jsonify({"error": "除数不能为零"}), 400
result = a / b
symbol = '÷'
else:
return jsonify({"error": "不支持的运算类型,支持:add, subtract, multiply, divide"}), 400
return jsonify({
"operation": operation,
"operands": {"a": a, "b": b},
"result": result,
"expression": f"{a} {symbol} {b} = {result}",
"timestamp": str(app.datetime.now()) if hasattr(app, 'datetime') else "N/A"
})
except (ValueError, TypeError):
return jsonify({"error": "请提供有效的数字参数"}), 400
except Exception as e:
return jsonify({"error": f"计算错误:{str(e)}"}), 500
# 获取所有支持的操作
@app.route('/operations')
def get_operations():
return jsonify({
"supported_operations": [
{"name": "add", "description": "加法运算", "example": "/add?a=10&b=5"},
{"name": "subtract", "description": "减法运算", "example": "/subtract?a=10&b=5"},
{"name": "multiply", "description": "乘法运算", "example": "/multiply?a=10&b=5"},
{"name": "divide", "description": "除法运算", "example": "/divide?a=10&b=5"}
],
"post_endpoint": {
"url": "/calculate",
"method": "POST",
"format": {
"a": "number",
"b": "number",
"operation": "string (add/subtract/multiply/divide)"
}
}
})
if __name__ == '__main__':
import datetime
app.datetime = datetime
app.run(debug=True)
📋 作业 3:完整的项目结构示例
flask_homework/
├── venv/ # 虚拟环境
├── app.py # 主应用文件
├── requirements.txt # 依赖文件
├── README.md # 项目说明
├── templates/ # 模板文件夹
│ ├── base.html
│ ├── index.html
│ └── profile.html
└── static/ # 静态文件夹
├── css/
│ └── style.css
└── js/
└── main.js
requirements.txt 内容:
Flask==2.3.3
Werkzeug==2.3.7
README.md 内容:
markdown
# Flask 学习项目
这是Flask课程第一课的作业项目。
## 功能特性
- 个人简介展示
- 计算器API
- 动态路由示例
- JSON API响应
## 安装运行
1. 创建虚拟环境:
```bash
python -m venv venv
source venv/bin/activate # Mac/Linux
-
安装依赖:
bashpip install -r requirements.txt
-
运行应用:
bashpython app.py
API 文档
详见代码注释和 /operations
端点。
---
## 💡 学习小贴士
### 🔍 调试技巧:
1. **使用调试模式**:`debug=True` 可以自动重载代码
2. **查看控制台输出**:运行时的错误信息很有帮助
3. **使用浏览器开发者工具**:检查网络请求和响应
4. **添加print语句**:在函数中添加打印语句来跟踪执行流程
### 🚀 进阶建议:
1. **学习使用Postman测试API**
2. **尝试添加错误处理和参数验证**
3. **探索Flask的官方文档和示例**
4. **练习编写单元测试**
### 📖 推荐阅读:
- [Flask官方文档](https://flask.palletsprojects.com/)
- [Flask快速入门教程](https://flask.palletsprojects.com/quickstart/)
- [Python Web开发最佳实践](https://docs.python-guide.org/scenarios/web/)
---