Django 管理图书和电影


项目仓库:(本仓库)


下文流程图概括了两条主链路:books 的「模板渲染 CRUD」与 movies 的「DRF API(分页/过滤/搜索/排序/限流/内容协商)」。

graph TD
    A[浏览器/客户端] -->|HTTP| B[Django URLConf]

    B -->|/books/| C[books 传统视图]
    C --> D[Book Model SQLite]
    C --> E[模板渲染]
    E --> A

    B -->|/books/api/books/| C2[books JSON API]
    C2 --> D2[Book Model SQLite]
    D2 --> C2
    C2 --> A

    B -->|/api/| F[movies DRF]
    F --> G[MovieViewSet APIView]
    G --> H[MovieSerializer]
    H --> I[Movie Model SQLite]
    I --> H
    H --> J[DRF Response]
    J --> A

    K[中间件] --> F
    K --> C
    K --> C2
    K -->|CORS| L[corsheaders]
    K -->|日志| M[RotatingFileHandler]

项目概述

本项目承担「Web 页面(模板渲染 CRUD)」与「REST API(DRF 标准接口)」两条链路的打通,在本项目中负责项目搭建、应用拆分、路由设计、模型与序列化器/视图实现,以及 DRF 的分页、过滤、限流与可浏览 API 配置。

技术栈:Django 作为 Web 骨架与模板渲染,Django REST Framework 承担 API 层,SQLite 作为开发数据库(db.sqlite3),django-filter 提供 DRF 精确过滤,django-cors-headers 支持跨域,Python logging 输出控制台与轮转文件日志。项目入口:后台 /admin/、书籍模块 /books/、电影 API 模块 /api/

类别 技术选型 用途
Web 框架 Django 传统视图、模板渲染、Admin 后台
API 框架 Django REST Framework REST API、可浏览 API、内容协商
数据库 SQLite 开发环境快速落库与迁移验证
过滤 django-filter DRF 精确过滤(?director=...
CORS django-cors-headers 前后端分离/跨域访问支持
日志 logging + RotatingFileHandler 控制台与文件日志、轮转保存

项目背景

学习 Django 时,常见痛点是只会写模板页面或只会写 API,缺少对工程结构、路由拆分、模型与序列化器协作以及 API 常用工程能力(分页、过滤、限流、内容协商)的系统性理解;若只有零散示例而缺少一条可运行、可演示的完整链路,也难以体现「能独立搭起可维护后端」的能力。本项目将「books(传统模板 CRUD)」与「movies(DRF 标准 API)」串联为一条可复用的实践链路,覆盖从模型、迁移、模板、Admin 到 DRF 的 ViewSet、Router、过滤与可浏览 API。

同时,为贴近真实工程,本项目补齐跨域(CORS)与工程日志能力,便于前后端分离联调与问题排查。


系统架构与选型

采用单 Django 工程 + 多 app 的组织方式:manshu_django/ 作为项目配置与根路由,业务拆分为 booksmovies 两个 app。根路由将 /books/ 交给 books.urls/api/ 交给 movies.urls,保留 Django Admin /admin/。请求经 URLConf 分发后,books 走传统视图与模板渲染,movies 走 DRF ViewSet 与序列化器;数据层统一使用 SQLite,配合迁移(makemigrations/migrate)快速验证模型与 CRUD 行为。

选型考量:Django 模板渲染可直观理解请求处理、表单提交与上下文传递,便于与 DRF 的纯 API 形成对照。DRF 的 DefaultRouter 为 ViewSet 自动生成标准 REST 路由,再叠加分页、过滤、限流与可浏览 API,可快速形成一致、可扩展的 API 结构。工程侧引入 corsheaders 支持跨域,通过 RotatingFileHandler 将日志输出到 logs/manshu_django.log,便于联调与排查。

关键技术选型理由

  • Django(books:模板 + 视图)

    通过模板渲染的 CRUD 可直观理解请求处理、表单提交(GET/POST)、重定向与模板上下文传递等 Web 基础能力,便于与 DRF 的纯 API 形成对照。

  • DRF + ViewSet + DefaultRouter(movies:标准 REST API)

    ViewSet 将 CRUD 行为标准化,Router 自动生成路由,能快速形成一致、可扩展的 API 结构;再叠加分页、过滤、搜索与排序,覆盖真实 API 常用需求。

  • django-filter(精确过滤)

    相比手写查询参数解析,DjangoFilterBackend 以声明式方式将 filterset_fields 暴露为查询能力(如 ?director=...&release_year=...),更清晰、可维护。

  • 可浏览 API 与格式后缀(内容协商)

    开启 BrowsableAPIRenderer 后,浏览器访问接口即可交互式调试;对普通视图启用 format_suffix_patterns,可用 URL 后缀显式指定返回格式(.json / .api),降低联调成本。


功能模块

模型与数据(Book / Movie)

  • Bookname(书名)、author(作者)、price(价格,DecimalField),表名 books,用于模板 CRUD 与轻量 JSON 接口。
  • Movietitledirectorrelease_yearratingdescriptioncreated_at/updated_at,表名 movies,由 DRF 序列化器暴露为 REST 资源;支持按导演/年份精确过滤、标题/导演搜索、年份/评分排序,便于权限与结果溯源(若后续扩展)。

books:模板渲染 CRUD(传统 Django 视图)

模块入口:/books/

核心功能

  • 书籍列表:展示所有书籍(模板:templates/books/book_list.html
  • 新增:/books/add/(POST 创建 Book
  • 编辑:/books/edit/<id>/(POST 更新 Book
  • 删除:/books/delete/<id>/

实现要点

  • 使用 render() 渲染模板,并通过 context 传递 books / book
  • 使用 redirect("/books/") 完成写操作后的跳转
  • 使用 get_object_or_404() 处理编辑时的不存在情况

books:JSON 列表接口(轻量 API)

模块入口:/books/api/books/

核心功能

  • 返回 id/name/author/price 字段的 JSON 列表
  • 响应结构统一为 {"code": 0, "data": [...]},便于前端消费

movies:DRF 标准 REST API(ViewSet)

模块入口:/api/movies/(由 DefaultRouter 自动生成)。

核心功能

  • 标准 CRUD:列表、新增、详情、更新、删除
  • 分页:全局 PAGE_SIZE = 10
  • 过滤/搜索/排序:
    • 精确过滤:?director=张三&release_year=2024
    • 搜索:?search=电影名
    • 排序:?ordering=release_year?ordering=-rating
  • 限流:匿名 100/hour、认证用户 1000/hour

内容协商

  • 默认渲染器同时支持 JSON 与可浏览 API(HTML)
  • 通过 Accept 请求头或格式后缀(视图类型不同,支持范围不同)决定返回内容

movies:示例接口(函数视图 / APIView)

核心功能

  • 函数视图:/api/movie-list/(支持 .json / .api 后缀)
  • 类视图:/api/movie-api/(同上)

用于展示:

  • request.data 对 JSON/表单等多格式请求体的统一处理
  • Response 的内容协商能力

管理后台(Django Admin)

入口:/admin/

核心功能

  • Book 已注册并做列表页增强:list_displaylist_filtersearch_fieldslist_editable、分页。
  • Movie 目前未在 admin.py 注册,可作为后续练习点。

工程能力:CORS 与日志

CORS

  • 已启用 corsheaders 中间件
  • 开发环境配置 CORS_ALLOW_ALL_ORIGINS = True(生产环境建议改为白名单)

日志

  • 控制台输出(DEBUG 模式下)
  • 文件日志:logs/manshu_django.log(轮转:最大约 300MB,保留 10 份)

测试

  • movies:提供 MovieAPITestCase,使用 DRF 的 APIClient 对电影列表等接口做请求级测试,便于理解 DRF 测试写法与 python manage.py test 的使用。
  • books:测试文件为占位,可作为后续补充列表/新增/编辑等用例的练习点。

技术难点与实现

同一工程中同时支持“模板 Web”与“REST API”

难点:模板渲染与 API 的开发范式不同(返回 HTML vs JSON),若路由与 app 边界不清晰,容易导致视图风格混杂、入口难以维护。

方案:采用按 app 拆分的路由组织方式,在根路由中将 /books//api/ 分流到不同 app 的 urls.py;books 专注传统视图与模板,movies 专注 DRF(Router/ViewSet/序列化器),降低耦合、便于扩展。效果上,两条链路清晰分离,新功能按模块扩展即可复用同一套能力。

DRF 列表接口的工程化能力(分页/过滤/搜索/排序/限流/内容协商)

难点:学习 API 时常停留在“能返回 JSON”,但缺少可复用的工程配置(分页、过滤、限流与内容协商),接口一旦增多会难以统一。

方案:在 settings.py 中统一配置 DRF:

  • 渲染器:JSON + 可浏览 API
  • 解析器:JSON / 表单 / 文件
  • 分页:PageNumberPagination + PAGE_SIZE
  • 过滤后端:DjangoFilterBackend + SearchFilter + OrderingFilter
  • 限流:AnonRateThrottle + UserRateThrottle

同时在 movies.urls 中对普通视图启用 format_suffix_patterns,让 .json / .api 的调试链路更直观。效果上,列表接口具备统一的分页与过滤行为,新接口只需挂到 Router 或配置 filter_backends 即可复用同一套能力,无需重复写逻辑。


总结

从模板 CRUD 到 DRF 标准 API,整条 Django + DRF 实践链路已打通;books 与 movies 并置、CORS 与日志等工程配置已按需求补齐,适合作为学习与复盘用的最小可运行工程。

后续可扩展方向包括:为 Movie 增加 Admin 配置、补充权限与认证(如 Session/JWT)、将 SQLite 替换为 MySQL/PostgreSQL、以及为 API 增加更完整的测试用例(Django TestCase / DRF APIClient)。