(二十三)模型、视图、权限与测试数据库
1. 用固定数据描述预期行为
Django 的 TestCase 为测试准备数据库隔离,setUpTestData 建立一组类级初始数据。实际数据文件继续保留,测试使用自己的库。
# 项目文件:reading_project/src/library/tests/base.py
from django.contrib.auth import get_user_model
from django.test import TestCase
from library.models import Book, Tag
class LibraryData(TestCase):
@classmethod
def setUpTestData(cls):
# 一组固定数据供本类测试使用,TestCase 为各个测试隔离数据库变化。
User = get_user_model()
cls.alice = User.objects.create_user("alice", password="learn-alice")
cls.bob = User.objects.create_user("bob", password="learn-bob")
cls.manager = User.objects.create_user(
"manager", password="learn-manager", is_staff=True
)
cls.tag = Tag.objects.create(name="基础")
cls.books = []
for number in range(1, 7):
book = Book.objects.create(
owner=cls.alice, title=f"Book {number}", finished=number in {2, 5}
)
book.tags.add(cls.tag)
cls.books.append(book)self.client 提供 Django 测试客户端。force_login 适合准备“已经登录”这一状态;真正的密码与会话流程另用登录表单和带 CSRF 检查的客户端核对。response.context 在测试环境中可以检查传入模板的表单和分页对象。
| 检查任务 | 实际核对内容 |
|---|---|
| 字段和组合唯一约束 | 书名、备注、标签错误;同用户重名失败、不同用户可同名 |
| 一次保存的多表事务 | 末步失败后书、标签、关联与记录回滚 |
| CRUD 与失败回填 | 跳转、错误表单、修改状态、消息一次显示与删除后 404 |
| 登录与来源检查 | 密码摘要、next 地址、令牌掩码、登录旋转和退出重放 |
| 用户与后台权限 | 普通用户归属、staff 与模型权限、后台列表及对象范围 |
| 查询执行 | 构造与缓存时机,实际 SQL 从 13 次减少到 2 次 |
| 命令重复执行 | 书目不重复、用户密码和已读状态保留 |
# 只运行 library 应用的测试,Django 自动创建并销毁测试数据库。
uv run python manage.py test library
完整代码见 模型与表单测试、视图与认证测试、后台与查询测试。
2. 单独检查真正的 CSRF 流程
Django 测试客户端默认方便业务测试,不强制 CSRF。Client(enforce_csrf_checks=True) 会实际检查隐藏字段、Cookie 和来源,配套认证测试用它先请求页面,再读取令牌提交。实际浏览器继续检查页面控件和网络跳转。