搞懂GET/POST/重定向:dj4e-samples getpost示例HTML表单原理深度剖析
【免费下载链接】dj4e-samplesDjango For Everybody Sample Code项目地址: https://gitcode.com/gh_mirrors/dj/dj4e-samples
学习 Django 时,HTML 表单是最绕不开的一环。本文带你使用dj4e-samples(Django For Everybody 官方示例代码库)中的getpost示例应用,一次搞懂GET 表单提交、POST 表单提交、CSRF 防护和 302 重定向的完整原理。无需死记硬背,跟着 10 个可运行的迷你页面逐个拆解,新手也能快速建立"请求-响应"的直觉。
为什么 GET、POST 和重定向必须一起学?
很多教程把三种提交方式分开讲,导致新手产生一个误区:以为"表单提交 = 发一次请求就结束了"。实际上真实业务中三者经常组合使用:
| 概念 | 数据放在哪 | 典型场景 | 关键特点 |
|---|---|---|---|
| GET | URL 查询字符串(?guess=42) | 搜索、筛选 | 可收藏、可分享,但有长度和隐私限制 |
| POST | 请求体(Request Body) | 登录、注册、提交资料 | 数据不暴露在地址栏,更私密 |
| 重定向 | HTTP 302 响应 + Location 头 | 提交成功后跳转 | 解决"刷新导致重复提交"的经典手段 |
dj4e-samples 的 getpost 模块把这三件事压缩进了一个小小的 Django 应用里,每个页面只演示一个知识点,是学习 Web 表单机制的绝佳素材。
3 分钟跑起来:getpost 示例安装步骤
拿到代码只需三步,完整环境搭建说明可参考项目根目录的 README.md:
git clone https://gitcode.com/gh_mirrors/dj/dj4e-samples cd dj4e-samples pip install -r requirements52.txt && python manage.py runserver启动后访问http://localhost:8000/getpost/,你会看到一个包含 10 个入口的导航页,模板文件就是 getpost/templates/getpost/main.html。所有 URL 规则集中在 getpost/urls.py,所有后端逻辑集中在 getpost/views.py——结构极其精简,非常适合边读边跑。
该模块在总路由中的挂载位置见 dj4e-samples/urls.py:
path('getpost/', include('getpost.urls')),GET 提交原理:数据藏在 URL 里
打开getform页面(对应视图 getpost/views.py 中的getform函数),提交一个猜测值后会看到两件事:
- 地址栏变化:URL 变成
/getpost/getform?guess=42,参数"长"在了地址栏上; - 页面下方打印数据:视图用
dumpdata('GET', request.GET)把收到的键值对全部回显出来。
这就是 GET 的本质——表单数据被序列化到 URL 查询字符串中。优点是页面可以被收藏和分享;缺点是:
- 敏感数据(如密码)绝不能走 GET;
- URL 有长度限制,不适合大段内容。
💡 观察技巧:浏览器 DevTools 的 Network 面板中,GET 请求的 Payload 一栏是空的,参数只在 Request URL 里可见。
POST 提交原理:数据装进请求体
postform页面(视图 getpost/views.py)的表单只多写了一个属性:<form method="POST">。提交后:
- 地址栏不变,依然是
/getpost/postform; - 猜测值被放在请求体中发送,通过
request.POST读取并回显。
注意这里视图加了@csrf_exempt装饰器——这是为了教学演示而刻意关闭Django 的 CSRF 保护。在生产代码中千万不要这么做,原因见下文 CSRF 一节。
经典输入控件全解析
html4和html5两个页面是"控件大全",提交后会把所有字段值打印出来,非常适合观察不同控件的提交差异:
- 文本/密码输入框:
<input type="text">、<input type="password"> - 单选框:同名
name的 radio 只会提交一个选中值 - 多选框:未勾选的 checkbox完全不出现在提交数据中(这是新手最常踩的坑)
- 下拉框:提交的是
<option>的value,不是显示文字 - 多行文本:
<textarea>直接提交完整内容
两个模板分别是 getpost/templates/getpost/html4.html 和 getpost/templates/getpost/html5.html,后者还演示了 HTML5 新增的color、date、email、number、url等类型,浏览器会自动提供原生校验和专用输入控件(如日期选择器)。
CSRF 防护:POST 表单的安全必修课
Django 默认对所有 POST 请求进行跨站请求伪造(CSRF)检查。getpost 模块用三个页面把这件事讲透了:
| 页面 | 做法 | 结果 |
|---|---|---|
failform | 普通 POST 表单,无 token | ❌ 被 Django 拦截,报 403 Forbidden |
csrfform | 表单内加隐藏字段csrfmiddlewaretoken | ✅ 校验通过,正常提交 |
guess | 模板中写{% csrf_token %} | ✅ Django 自动注入 token |
对比 getpost/views.py 中的failform和csrfform:后者通过get_token(request)取到 token,再手动塞进<input type="hidden">。而在真实项目里,你只需要像 getpost/templates/getpost/guess.html 那样在模板里写一行{% csrf_token %},Django 会自动完成注入。
🛡️ 记忆口诀:GET 无副作用,POST 必带 token。
猜数字小游戏:函数视图 vs 类视图
模块里用同一个"猜 42"的游戏写了三个版本,是理解 Django 视图演进的最好教材:
1️⃣ 函数视图guess(getpost/views.py):只能处理 POST,每次提交后直接渲染页面。缺点是你的浏览器地址停在这个页面上,按 F5 刷新会再次提交表单。
2️⃣ 类视图classy(getpost/views.py):同一个类里get()负责渲染表单、post()负责处理提交。URL 写法变为ClassyView.as_view(),同一个 URL 按请求方法自动分发。
3️⃣ Awesome 版AwesomeView(getpost/views.py):POST 处理完后不直接返回页面,而是把提示消息存进 session,然后执行redirect(request.path)发起 302 重定向;下一次 GET 请求取出消息、从 session 中删掉并渲染。
重定向:PRG 模式如何终结"刷新重复提交"
这正是bounce和awesome两个页面要解决的问题。流程如下:
- 用户点击提交 → 服务器处理 POST,返回302和
Location头; - 浏览器自动跳转 → 发出一个新的GET请求;
- 用户此时按 F5 刷新 → 只会重复这个无害的 GET,不会重复提交。
这套"POST → Redirect → GET"(简称PRG)模式是几乎所有 Web 框架的标准答案。bounce视图(getpost/views.py)则是一个极简版演示:直接返回HttpResponseRedirect,让你有机会在 DevTools 里亲眼看到 302 状态码和Location响应头长什么样。
学习路径与文件地图
建议按以下顺序通读代码,每个文件都不长:
| 文件 | 学什么 |
|---|---|
| getpost/urls.py | 10 条路由如何对应 10 个演示页面 |
| getpost/views.py | dumpdata回显技巧、GET/POST 读取、CSRF token、302 重定向 |
| getpost/templates/getpost/main.html | 纯静态导航页(用TemplateView直接渲染) |
| getpost/templates/getpost/guess.html | {% csrf_token %}的正确姿势 |
| getpost/templates/getpost/html4.html | radio / checkbox / select / textarea 提交差异 |
| getpost/templates/getpost/html5.html | HTML5 新型 input 类型 |
学完 getpost 后,可以继续看同仓库的 form/ 模块(Django Form 类表单)和 crispy/ 模块(Bootstrap 美化表单),从"手写 HTML 表单"平滑过渡到"框架表单"。
总结:一张图记住三大要点
- GET:数据进 URL,能分享、有上限、别传敏感信息;
- POST:数据进请求体,配合CSRF token防跨站伪造;
- 重定向(302):提交成功后跳转,实现PRG 模式,告别"刷新重复提交"。
dj4e-samples 的 getpost 模块用不到 130 行视图代码 + 5 个模板,把 Web 表单的核心机制全部演示了一遍。跑一遍、改一改、用 DevTools 看一眼,你对"浏览器-服务器"之间发生的事就会有扎实的体感。
【免费下载链接】dj4e-samplesDjango For Everybody Sample Code项目地址: https://gitcode.com/gh_mirrors/dj/dj4e-samples
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考