重构: Day_2拆分/Day_3延后为Day_4-6/Django改为进阶任务

This commit is contained in:
2026-08-18 00:21:04 +08:00
parent 16e8724fcd
commit 604b9b37c1
6 changed files with 0 additions and 966 deletions
-112
View File
@@ -1,112 +0,0 @@
# Day_4 · 设计一个真正的 Django 小应用
> 前提:你应该已经跟着教程跑通了 Django 的安装,执行过
> `django-admin startproject mysite` 和 `python manage.py startapp blog`,
> 知道 `settings.py` / `urls.py` / `views.py` / `models.py` 大概长什么样。
> 今天不是"照着教程敲一遍",而是"**先想清楚,再动手设计**"。
> 题目里每一步都问了为什么——能回答上,才算真的懂了。
## 今日目标
做一个**社团招新管理系统**:成员(Member)发布文章(Article),成员可以评论(Comment)。
覆盖:模型设计、ORM 查询、视图、URL 路由、模板、以及"从请求到响应"的完整链路。
## 环境准备
```bash
pip install django
django-admin startproject mysite
cd mysite
python manage.py startapp blog
# 记得把 'blog' 加进 settings.py 的 INSTALLED_APPS
```
---
## 题目一(必做):设计数据模型 models.py
**背景**:一个博客/招新系统,核心数据是"文章",文章有作者,作者是社团成员,文章下面有评论。
**要求**:在 `blog/models.py` 里写出完整代码,包含三个模型:
1. **Member**(成员):昵称 `nickname`、邮箱 `email`(要**唯一**)、
加入时间 `joined_at`(自动记录创建时间)、简介 `bio`(允许为空)
2. **Article**(文章):标题 `title`、正文 `content`、作者 `author`
(外键 → Member,作者被删时文章级联删除)、是否发布 `is_published`(默认 False)、
发布时间 `created_at`(自动记录)、浏览量 `views`(默认 0)
3. **Comment**(评论):正文 `content`、所属文章 `article`
(外键,`related_name="comments"`)、评论者 `commenter`(外键 → Member)
四个要求:
- 三个模型都要有合理的 `__str__`(Article 返回标题,Comment 返回"评论者 + 内容前 20 字",Member 返回昵称)
- 用 `Meta` 设置排序:Article 按 `created_at` 倒序,Comment 按 `id` 正序
- 字段参数用对:`max_length`、`default`、`null=True`/`blank=True` 该加的地方要加
- 思考题写进注释里(各一两句即可)
**思考题(写进注释)**:
1. 为什么外键要用 `on_delete=models.CASCADE`?如果改成 `SET_NULL` 会发生什么、需要什么前提?
2. `related_name="comments"` 是干什么的?(提示:`article.comments.all()` 是什么?)
---
## 题目二(必做):写视图 + ORM 查询 views.py
**要求**:在 `blog/views.py` 里写四个视图函数:
1. **`index(request)`**:查出所有**已发布**的文章(`is_published=True`),按时间倒序,
渲染 `index.html`,把文章列表传进模板
2. **`article_detail(request, pk)`**:用 `get()` 取单篇文章,**不存在时抛 `Http404`**;
浏览量 +1 并保存;渲染 `detail.html`
3. **`add_comment(request, pk)`**:POST 请求时读取 `request.POST` 里的 `content`,
创建一条评论(评论者先用 `Member.objects.first()` 随便取一个,我们还没做登录),
完成后**重定向**回文章详情页;GET 请求也直接重定向回详情页
4. **(进阶)`author_articles(request, nickname)`**:按作者昵称查该作者的全部文章,
并且**用 ORM 统计每篇文章的评论数**(提示:`annotate` + `Count`,配合 `related_name`),
渲染 `author.html`。想不出 `annotate` 就先用 Python 算,但要写一句注释说明两种做法的区别
**思考题(写进注释)**:
- 浏览量 +1 有两种写法:
a) `article.views += 1; article.save()`
b) `Article.objects.filter(pk=pk).update(views=F("views") + 1)`
两个请求同时点击文章时,a 会出什么问题?b 为什么没问题?(提示:并发 / 原子性)
---
## 题目三(必做):URL 路由 + 完整链路说明
**要求**:
1. 写出项目级 `urls.py`(含 `include`)和应用级 `blog/urls.py`,路由表覆盖:
- 列表页 `""` → `index`
- 文章详情 `/article/<int:pk>/` → `article_detail`
- 提交评论 `/article/<int:pk>/comment/` → `add_comment`
- 作者文章页 `/author/<str:nickname>/` → `author_articles`
每个路由都要起 `name`。
2. **写一段话(150 字内)**:用户在浏览器输入 `/article/3/` 回车后,
从"请求到响应"经历了哪些环节?必须提到:URL 匹配、视图函数、
ORM 查询、`render`、模板、`HttpResponse` 这几个词。
3. **(进阶)** 给出 `index.html` 的模板片段:
- 用 `{% for %}` 循环展示文章标题和"查看详情"链接
- 用模板过滤器把 `created_at` 格式化成 `Y-m-d H:i`
- 空列表时显示"暂无文章"
---
## 完成标准
- [ ] 题目一:三个模型写全,思考题有自己的答案(不必和参考一致,能自圆其说就行)
- [ ] 题目二:四个视图能跑通,`python manage.py runserver` 后列表页、详情页、评论、作者页都能访问
- [ ] 题目三:路由表写全 + 链路说明写出来(进阶则 +1)
**验收动作(强烈建议)**:跑起来 `runserver`,在浏览器里真的走一遍
"打开列表页 → 点进文章 → 提交评论 → 回到详情页看到评论"。
能跑通,说明 Day_4 真正过关。
完成后打开 `参考解答.md` 对照。
> 进度提示:Day_4 做完,你就完成了"基础语法 → 面向对象 → 框架实战"的完整闭环。
> 下一步可以自己加功能:分页、搜索、`@login_required`、用 Celery 给文章作者发通知……
> 每加一个功能,都是一次新的练习。