Files
DailyChallenge_ProgrammingD…/Day_2/README.md
T

99 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Day_2 · 字典与字符串:先学会"接住"请求
> 后端程序每天都在处理两样东西:**字典**(各种参数、数据记录)和**字符串**(URL、文本)。
> 今天的两道题只用到基础语法,但都是后端最真实的日常。
> 做完它们,你就拿到了读懂 Django 的第一把钥匙。
## 今日知识点 → 以后在 Django 里对应什么
| 今天练的 | 以后在 Django 里会看到 |
| --- | --- |
| 列表 + 字典的筛选、排序 | ORM 查询结果(QuerySet)的循环处理 |
| 字符串分割与格式化 | URL 路由解析、模板渲染、日志输出 |
| 字典的增删改查 | `request.GET` / `request.POST`、JSON 响应 |
---
## 题目一(热身):模拟查询结果的处理
**背景**:ORM 查数据库,拿回来的是"一堆记录",每条记录就是一个字典。
以后你天天和这种东西打交道。今天先热身。
**要求**:造一个用户列表(`list[dict]`,4~5 条),字段:`name`、`age`、`city`。然后:
1. 筛出**年龄 ≥ 18** 的用户(提示:列表推导式 `[u for u in users if ...]`)
2. 按**年龄从大到小**排序(提示:`sorted(users, key=lambda u: u["age"], reverse=True)`)
3. 输出 `zhangsan(20岁)` 这种格式的字符串列表(提示:f-string)
4. **进阶(加分)**:把上一步的结果用 `", "` 拼成一个字符串输出
**输入输出示例**
```
users = [
{"name": "zhangsan", "age": 20, "city": "青岛"},
{"name": "lisi", "age": 17, "city": "济南"},
{"name": "wangwu", "age": 22, "city": "北京"},
]
筛选 ≥18: [{'name': 'zhangsan', ...}, {'name': 'wangwu', ...}]
按年龄降序: wangwu, zhangsan
字符串列表: ['wangwu(22岁)', 'zhangsan(20岁)']
进阶拼接: 'wangwu(22岁), zhangsan(20岁)'
```
**出题意图**:`filter` + `order_by` 在 Django 里是 `objects.filter(age__gte=18).order_by("-age")`——今天你用纯 Python 先把同样的思维练熟。
---
## 题目二(必做):解析 URL 查询参数
**背景**:浏览器访问 `https://example.com/register?username=zhangsan&age=20&city=qingdao`,
`?` 后面的 `username=zhangsan&age=20&city=qingdao` 叫做**查询参数(query string)**。
Django 里 `request.GET` 就是帮你解析好的字典。今天我们手写一个解析器,看清它背后发生了什么。
**要求**:写函数 `parse_query_string(query)`,输入一行查询参数(不含 `?`),返回一个字典。
必须处理的边界情况:
1. 空输入 → 返回空字典 `{}`
2. 重复键,如 `name=a&name=b` → 后者覆盖前者:`{'name': 'b'}`
3. 参数没有 `=`,如 `flag` → 值为空字符串:`{'flag': ''}`
4. 值为空,如 `name=` → `{'name': ''}`
**输入输出示例**
```
输入: username=zhangsan&age=20&city=qingdao
输出: {'username': 'zhangsan', 'age': '20', 'city': 'qingdao'}
输入: name=a&name=b&flag
输出: {'name': 'b', 'flag': ''}
输入: (空字符串)
输出: {}
```
**进阶(加分)**:URL 编码还原——把值中的 `+` 还原为空格,`%20` 也还原为空格。
如 `name=Zhang+San` → `{'name': 'Zhang San'}`。
> 提示:
> - 先 `split('&')` 把整体切成若干段,再对每一段 `split('=', 1)`。
> 想想为什么 `maxsplit` 要写成 1?(如果值里本身就含 `=` 会怎样?)
> - 字典赋值 `d[key] = value` 天然处理了"覆盖"和"空值"两种情况。
**出题意图**:Django 的 `QueryDict`(`request.GET`)底层干的就是这件事。
把它吃透,以后看到 `request.GET.get('page')` 就不再是黑魔法,而是老朋友。
---
## 完成标准
- [ ] 题目一四步全部跑通(含进阶则 +1)
- [ ] 题目二 4 个边界情况全部通过(含进阶则 +1)
完成后打开 `参考解答.py` 对照。建议看完后关掉文件,自己再默写一遍。
> 写给还没开始的你:这系列是递进关系——
> Day_2 字典/字符串 → Day_3 函数/异常 → Day_4~Day_6 面向对象 → 进阶_Django 实战。
> 每天只做必做题,也足够支撑你开学后跟上节奏。