Python 现代开发学习笔记

(三)表单字段与 JSON 数据

1. GET 表单把具名字段组成查询串

先只做读取:用下拉框选择已读状态。下面的 HTML 文件放在 samples 中,登录后提交就会打开对应 API 地址。

<!-- 项目文件:samples/filter_form.html -->
<!-- GET把具名字段放进查询串,只筛选列表,不新增记录。 -->
<!doctype html><html lang="zh-CN"><meta charset="utf-8"><title>筛选已读状态</title>
<form method="get" action="http://127.0.0.1:8767/api/books">
  <label>阅读状态
    <select name="finished">
      <option value="all">全部</option>
      <option value="0">未读</option>
      <option value="1">已读</option>
    </select>
  </label>
  <button type="submit">查看记录</button>
</form></html>

form 的 method 指定 GET,action 指定目标地址。select 的 name 决定字段名,选项的 value 决定提交值;选择未读后得到 ?finished=0。label 给控件提供说明,button 的 submit 类型触发表单提交。

书架的新增表单使用 POST,把字段编码进请求体。输入框的 name 仍然决定字段名;没有 name 的控件不会以这个字段提交。未勾选的复选框通常不提交那一项,因此服务器要把“缺少已读勾选”转换为 False。

2. 编码形式决定解析过程

# 项目文件:demos/urls_forms.py
# URL中的查询和请求体分别编码;parse_qs保留同名字段的多值结构。
import json
from urllib.parse import parse_qs, urlencode, urlsplit

url = urlsplit("http://127.0.0.1:8767/api/books?finished=0")
print("地址", url.scheme, url.netloc, url.path, parse_qs(url.query))
encoded = urlencode({"title": "Python Web", "tags": "Python,网络"})
print("表单编码", encoded)
print("恢复字段", parse_qs(encoded))
raw = json.dumps(
    {"title": "Python Web", "finished": False, "tags": ["网络"]}, ensure_ascii=False
)
print("JSON类型", type(json.loads(raw)["finished"]).__name__)

urlsplit 分开协议、主机与端口、路径和查询串;parse_qs 将查询串或表单正文读成“字段名对应值列表”。值是列表,因为同一个名称可以出现多次,本章的单值字段会另外核对次数。

urlencode 处理空格、中文和分隔符。Python Web 中的空格可编码为加号,中文与逗号通过百分号编码保存;解析后恢复字段文本。application/x-www-form-urlencoded 指明这种表单格式。

JSON 的 false 则在解析后成为 Python 的 False,数组成为 list。Content-Type: application/json 告诉服务器采用 JSON 解析;把请求体里的文本改得像 JSON,却仍声明表单类型,不会自动切换解析方式。

HTML表单先编码为字段文本再逐项转换,JSON先恢复布尔和列表,两条路径汇合为同一份书籍草稿

笔记正文与全部题解 · Ctrl / ⌘ K