180分钟从零到部署:我这样教学生搭建电影搜索网站

起因:180分钟的挑战

近日受邀给外经贸大学的学生上两节Python课,每节90分钟。学生有基础,但缺实战经验。

目标很明确:让每个学生在课程结束时,都能拿出一个可以展示的完整项目

最初想用Django + 爬虫,但很快放弃了:

  • Django配置太重,两节课讲不完
  • 爬虫不稳定,容易翻车
  • 技术栈有点老了

我需要一个更简单、更现代、更可靠的方案。

技术选型:FastAPI + TMDB

为什么是FastAPI?

5行代码就能启动一个API:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

对比Django需要配置一堆东西,FastAPI的优势太明显:

  • ✅ 自动生成API文档(访问 /docs 就能测试)
  • ✅ 类型提示(现代Python最佳实践)
  • ✅ 性能优秀(比Django快很多)
  • ✅ 学习曲线平缓

为什么是TMDB?

豆瓣API早就关了,测试第三方接口也都404。TMDB才是正解:

$ curl "https://api.themoviedb.org/3/search/movie?api_key=xxx&query=肖申克&language=zh-CN"
  • ✅ 官方免费API
  • ✅ 支持中文
  • ✅ Netflix在用,够稳定
  • ✅ 1分钟申请Key

双模式设计:降低门槛的关键

课堂上最怕什么?学生环境配不好,API申请不下来。

我的解决方案:模拟数据 + 真实API,双模式切换

模式一:开箱即用

# .env
USE_MOCK_DATA=True  # 默认模式

# 内置模拟数据
mock_movies = [
    {"id": 1, "title": "肖申克的救赎", "vote_average": 9.3},
    {"id": 2, "title": "霸王别姬", "vote_average": 9.6}
]

下载代码,直接运行,无需配置。第一节课专注讲概念。

模式二:真实体验

# .env
USE_MOCK_DATA=False
TMDB_API_KEY=你的key

# 自动检测
if USE_MOCK_DATA or not TMDB_API_KEY:
    return mock_data()
else:
    return call_tmdb_api()

课后申请Key,改一行配置,立即切换到真实数据。

课程设计:三步走战略

第一节课:从Hello到API(90分钟)

Step 1: Hello FastAPI (20分钟)

@app.get("/hello/{name}")
def greet(name: str):
    return {"message": f"Hello, {name}!"}

学会:路由、参数、返回值

Step 2: 电影API (20分钟)

@app.get("/movies")
def get_movies(genre: str = None):
    return filter_movies(genre)

学会:RESTful设计、查询参数

Step 3: TMDB集成 (30分钟)

@app.get("/search")
async def search(q: str):
    return await call_tmdb(q)

学会:异步编程、API调用、环境变量

第二节课:完整应用(90分钟)

  • 前端界面 (25分钟):Jinja2、响应式布局
  • 功能完善 (30分钟):AJAX、收藏、统计
  • 部署准备 (20分钟):配置管理、GitHub

实战中的三个坑

1. 页面闪烁

// ❌ 问题
document.getElementById('list').innerHTML = '加载中...';

// ✅ 解决:加状态锁
let isLoading = false;
if (isLoading) return;
isLoading = true;

2. 中文URL编码

# ❌ 错误
curl 'http://localhost:8000/search?q=阿甘正传'

# ✅ 正确
curl --data-urlencode "q=阿甘正传" -G 'http://localhost:8000/search'

3. 虚拟环境失效

重命名项目后虚拟环境失效?因为内部保存了绝对路径。

rm -rf venv
python3 -m venv venv
source venv/bin/activate

配置管理:API Key别泄露

# ❌ 危险
TMDB_API_KEY = "444d85..."  

# ✅ 正确
# .env
TMDB_API_KEY=你的key

# config.py
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("TMDB_API_KEY", "")
.env
*.pyc
__pycache__/
venv/

教学设计的五个原则

1. 降低门槛,提高天花板

  • 模拟数据让所有人都能跑起来
  • 真实API让高手有进阶空间

2. 渐进式学习

  • Step 1: Hello World(建立信心)
  • Step 2: 基础API(理解概念)
  • Step 3: 真实集成(接触实战)
  • Lesson 2: 完整应用(综合运用)

3. 预设问题

学生肯定会遇到的问题,提前在文档里写好答案:

  • 虚拟环境配置
  • API Key申请
  • 中文参数编码
  • 端口占用

4. 真实但不复杂

  • ✅ 用真实技术栈(FastAPI、TMDB)
  • ❌ 不引入数据库、认证、复杂异步
  • ✅ 聚焦核心概念

5. 提供扩展方向

### 进阶挑战
1. 添加用户登录
2. 数据库持久化
3. 部署到云服务器
4. 实现推荐算法

技术对比

FastAPI vs Flask vs Django

特性FastAPIFlaskDjango
学习曲线⭐⭐⭐⭐⭐⭐
自动文档
适合教学

结论:两节课教学,FastAPI最优。

TMDB vs 豆瓣

API状态推荐度
TMDB稳定免费⭐⭐⭐⭐⭐
豆瓣已关闭

结论:TMDB是唯一选择。

文档的力量

我准备了完整的文档体系:

  • README.md:项目总览
  • STUDENT_GUIDE.md:详细教程(含API申请步骤)
  • teaching_guide.md:90分钟时间表
  • exercises.md:练习题

甚至提供了TMDB申请表的英文模板,学生直接复制粘贴就行。

好的文档就是好的设计。如果你无法用简单语言解释一个设计,说明设计有问题。

测试清单

虽然是教学项目,但我还是测试了所有功能:

# Lesson 1
 Hello World
 路径参数
 查询参数  
 RESTful API
 模拟数据模式
 真实API模式

# Lesson 2
 搜索功能
 热门榜单
 收藏系统
 统计分析
 响应式布局

发现并修复了:模拟数据格式错误、404问题、URL编码、页面闪烁等bug。

写在最后

从想法到实现,这个项目经历了:

  • 📊 3次技术栈调整
  • 🔧 5次重大重构
  • 📝 完整的文档
  • ✅ 全面的测试
  • ⏰ 20+小时准备

但这是值得的。180分钟内,学生能:

  • ✨ 体会编程乐趣
  • 💡 理解Web核心概念
  • 🚀 接触真实开发流程
  • 🎯 获得可展示的项目

更重要的是,展示了工程师的思考方式

  1. 理解约束(时间、水平)
  2. 技术选型(FastAPI + TMDB)
  3. 设计方案(双模式、渐进式)
  4. 工程实践(配置、文档、测试)

项目已开源:https://github.com/Polly2014/tmdb_movie_sourse

欢迎Star、Fork,更欢迎提Issue分享你的想法!

留言与讨论