# 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 实战。 > 每天只做必做题,也足够支撑你开学后跟上节奏。