表单与用户输入
这是什么:表单 = 网页上让用户填东西、点按钮的那块区域,比如搜索框和留言框。
为什么用:前两章都是网站「说」、用户「听」,网站始终是单向的。想让用户往网站里输入内容——搜索、登录、留言——没有表单就无从下手。
如何用:本章先分清 GET 和 POST 两种递数据的方式,再动手做一个留言板。
GET 与 POST:两种递纸条的方式
浏览器把数据发给服务器,最常用两种方式:
| GET | POST | |
|---|---|---|
| 数据放在哪 | 网址后面,形如 /search?keyword=猫(问号后面的部分叫查询字符串) |
请求体里,网址上看不到 |
| 适合 | 搜索、翻页这类「要数据」 | 提交留言、登录这类「给数据」 |
| 能收藏分享吗 | 能,参数就在网址里 | 不能,数据不进网址 |
| Flask 怎么取 | request.args.get("keyword") |
request.form.get("message") |
经验法则:只读用 GET,会改动东西(写入)用 POST。
动手做一个留言板
项目结构(沿用上一章的规矩,HTML 全放 templates):
hello-board/
├── app.py
└── templates/
└── board.html
templates/board.html:
<h1>留言板</h1>
{% for m in messages %}
<p>{{ m }}</p>
{% endfor %}
<form method="post" action="/add">
<input name="message" placeholder="写下你的留言">
<button type="submit">提交</button>
</form>
app.py:
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
messages = [] # 用列表存留言;程序一重启就清空,下一章用数据库解决
@app.route("/")
def home():
return render_template("board.html", messages=messages)
@app.route("/add", methods=["POST"]) # 这个门牌只收 POST
def add():
text = request.form.get("message", "").strip()
if text:
messages.append(text)
return redirect("/") # 回到首页,刷新就能看到新留言
if __name__ == "__main__":
app.run(debug=True)
运行 python app.py,访问 http://127.0.0.1:5000:输入留言、点提交,页面刷新,留言出现在列表里。试试直接在地址栏访问 http://127.0.0.1:5000/add?会报 405 Method Not Allowed——地址栏敲回车是 GET 请求,而这个门牌只收 POST「包裹」。
逐行解读
| 代码 | 作用 |
|---|---|
<form method="post" action="/add"> |
表单:点击提交时,把输入框们打包 POST 到 /add |
<input name="message"> |
name 是数据的快递单号,Flask 靠它取值 |
methods=["POST"] |
该路由只接受 POST 请求(不写时默认只接受 GET) |
request.form.get("message", "") |
从请求体里取 message;取不到就给默认值空字符串 |
.strip() |
去掉两头的空格,防手滑 |
redirect("/") |
让浏览器重新访问首页(重新 GET 一次,看到最新列表) |
两个补充:如果数据是挂在网址上的(比如 /add?message=你好),就要用 request.args.get("message") 来取——args 对应网址,form 对应请求体。另外,模板会自动转义特殊字符,所以放心用 `{{ }}` 显示用户输入的内容,比手拼 HTML 字符串安全得多。
记忆口诀
只读用 GET,写入用 POST;name 是单号,form 取体、args 取址。
动手改
- 加一个「清空留言」功能:新路由
/clear,把列表清空后重定向回首页 - 给留言板加个搜索框:用 GET 提交到
/search,取网址参数过滤出包含关键词的留言 - 把
methods=["POST"]改成methods=["GET", "POST"],想一想:什么场景下同一个网址需要两种请求都收?
下一章:数据库入门,让留言在重启后也活得下来 🐸