表单层 Form
表单层的作用,不只是生成输入框,更重要的是统一收集和校验用户提交的数据。
很多初学者一开始觉得表单层只是“写个表单页面”,但真正的网站开发里,表单更关键的意义在于:
- 统一字段定义
- 统一校验规则
- 统一错误提示
本节目标
- 理解 Django Form 的作用
- 学会定义最基础的表单类
- 学会在视图中接收和校验表单
- 学会在模板中渲染表单
- 学会使用
is_valid()和cleaned_data - 理解自定义校验和 CSRF 的意义
为什么需要表单层
当然,你完全可以不写 Form,直接在视图里这样取数据:
username = request.POST.get("username")
password = request.POST.get("password")这样能不能用?能。
但问题在于:
- 校验逻辑会散落在很多地方
- 错误提示不统一
- 表单字段越来越多时很难维护
所以 Form 层的意义就在于:把“输入字段定义 + 校验规则”收拢到一起。
定义一个最基础的表单
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(max_length=20)
password = forms.CharField(max_length=20, widget=forms.PasswordInput)这里定义了两个字段:
- 用户名
- 密码
PasswordInput 的作用
它会让密码输入框在页面中显示为密文样式,而不是直接明文显示。
在视图中使用表单
from django.shortcuts import render
from .forms import LoginForm
def login_view(request):
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
return render(request, "success.html")
else:
form = LoginForm()
return render(request, "login.html", {"form": form})这段代码非常关键,因为它展示了 Django 表单的基本使用套路。
GET 请求时
form = LoginForm()表示生成一个空表单给用户填写。
POST 请求时
form = LoginForm(request.POST)表示把用户提交的数据交给表单类处理。
is_valid() 的意义
这一句是整个表单处理的关键:
form.is_valid()它的作用是:
- 按照你定义的字段规则去校验用户输入
如果返回:
True说明数据符合要求。
如果返回:
False说明输入不合法。
获取校验通过后的数据
只有在 form.is_valid() 为真之后,才应该去拿 cleaned_data。
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]cleaned_data 可以理解成:
- 已经通过校验、可放心使用的数据
模板中渲染表单
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">登录</button>
</form>这里:
form.as_p表示把表单字段按段落形式渲染出来{% csrf_token %}是 Django 的安全防护机制
form.as_p、form.as_table、form.as_ul
你会看到几种常见渲染方式:
段落形式
{{ form.as_p }}表格形式
{{ form.as_table }}列表形式
{{ form.as_ul }}零基础阶段最常用的是 as_p。
一个完整登录表示例
表单类:
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(max_length=20, label="用户名")
password = forms.CharField(
max_length=20,
label="密码",
widget=forms.PasswordInput
)视图:
from django.shortcuts import render
from .forms import LoginForm
def login_view(request):
message = ""
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
message = f"欢迎你,{username}"
else:
message = "表单校验失败"
else:
form = LoginForm()
return render(request, "login.html", {
"form": form,
"message": message
})模板:
<h1>登录页面</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">登录</button>
</form>
<p>{{ message }}</p>这个例子已经把表单层最常见的流程走通了:
- 定义字段
- 接收提交
- 校验数据
- 获取清洗后的数据
- 返回结果
自定义校验
当默认规则不够时,可以自己写校验逻辑。
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(max_length=20)
password = forms.CharField(max_length=20, widget=forms.PasswordInput)
def clean_username(self):
username = self.cleaned_data["username"]
if username == "admin":
raise forms.ValidationError("这个用户名不能使用")
return username这里的意义是:
- 在字段默认校验通过后
- 再执行你自定义的业务规则
CSRF 为什么必须知道
你在 Django 表单模板中经常会看到:
{% csrf_token %}它不是装饰品,而是 Django 为 POST 请求提供的安全保护。
如果你忘了写它,很多 POST 提交会直接失败。
零基础阶段你先记住:
- 表单 POST 提交时基本都要写
- 这是 Django 的安全机制
表单层在真实项目中的常见场景
它特别适合这些页面:
- 登录页
- 注册页
- 修改密码页
- 搜索页
- 资料填写页
也就是说,只要页面涉及“用户输入并提交”,Form 层就通常有价值。
常见错误
1. 没调用 is_valid() 就直接取 cleaned_data
这会导致逻辑不安全,也不符合表单使用流程。
2. 忘记在模板中写 {% csrf_token %}
很多 POST 表单提交失败都和这个有关。
3. 表单类定义了字段,但视图没把 POST 数据传进去
正确写法应该是:
form = LoginForm(request.POST)4. 以为 Form 只是“生成 HTML”
真正更重要的,是它的校验能力。
练习题
练习 1
定义一个注册表单,包含:
- 用户名
- 密码
- 邮箱
练习 2
在视图中接收这个表单,并判断 is_valid() 是否通过。
练习 3
在模板中把表单渲染出来,并加上提交按钮。
练习 4
为用户名写一个自定义校验规则,禁止使用某个保留词。
练习 5
自己总结:为什么有了 request.POST.get() 之后,Django 还要专门提供 Form 层。
本节小结
Form 层最重要的价值,不是“多写了一层代码”,而是把表单字段定义和数据校验统一管理起来。
你这一节最重要的收获应该是:
- 会定义基础表单
- 会在视图中接收和校验表单
- 会在模板中渲染表单
- 理解
is_valid()和cleaned_data - 知道自定义校验和 CSRF 的意义
只要这一层掌握住,后面做 Django 登录、注册、资料填写这些页面时,就会有很清晰的套路。