Skip to content

表单层 Form

表单层的作用,不只是生成输入框,更重要的是统一收集和校验用户提交的数据。

很多初学者一开始觉得表单层只是“写个表单页面”,但真正的网站开发里,表单更关键的意义在于:

  • 统一字段定义
  • 统一校验规则
  • 统一错误提示

本节目标

  • 理解 Django Form 的作用
  • 学会定义最基础的表单类
  • 学会在视图中接收和校验表单
  • 学会在模板中渲染表单
  • 学会使用 is_valid()cleaned_data
  • 理解自定义校验和 CSRF 的意义

为什么需要表单层

当然,你完全可以不写 Form,直接在视图里这样取数据:

python
username = request.POST.get("username")
password = request.POST.get("password")

这样能不能用?能。
但问题在于:

  • 校验逻辑会散落在很多地方
  • 错误提示不统一
  • 表单字段越来越多时很难维护

所以 Form 层的意义就在于:把“输入字段定义 + 校验规则”收拢到一起。

定义一个最基础的表单

python
from django import forms


class LoginForm(forms.Form):
    username = forms.CharField(max_length=20)
    password = forms.CharField(max_length=20, widget=forms.PasswordInput)

这里定义了两个字段:

  • 用户名
  • 密码

PasswordInput 的作用

它会让密码输入框在页面中显示为密文样式,而不是直接明文显示。

在视图中使用表单

python
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 请求时

python
form = LoginForm()

表示生成一个空表单给用户填写。

POST 请求时

python
form = LoginForm(request.POST)

表示把用户提交的数据交给表单类处理。

is_valid() 的意义

这一句是整个表单处理的关键:

python
form.is_valid()

它的作用是:

  • 按照你定义的字段规则去校验用户输入

如果返回:

python
True

说明数据符合要求。
如果返回:

python
False

说明输入不合法。

获取校验通过后的数据

只有在 form.is_valid() 为真之后,才应该去拿 cleaned_data

python
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]

cleaned_data 可以理解成:

  • 已经通过校验、可放心使用的数据

模板中渲染表单

html
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">登录</button>
</form>

这里:

  • form.as_p 表示把表单字段按段落形式渲染出来
  • {% csrf_token %} 是 Django 的安全防护机制

form.as_pform.as_tableform.as_ul

你会看到几种常见渲染方式:

段落形式

html
{{ form.as_p }}

表格形式

html
{{ form.as_table }}

列表形式

html
{{ form.as_ul }}

零基础阶段最常用的是 as_p

一个完整登录表示例

表单类:

python
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
    )

视图:

python
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
    })

模板:

html
<h1>登录页面</h1>

<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">登录</button>
</form>

<p>{{ message }}</p>

这个例子已经把表单层最常见的流程走通了:

  1. 定义字段
  2. 接收提交
  3. 校验数据
  4. 获取清洗后的数据
  5. 返回结果

自定义校验

当默认规则不够时,可以自己写校验逻辑。

python
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 表单模板中经常会看到:

html
{% csrf_token %}

它不是装饰品,而是 Django 为 POST 请求提供的安全保护。

如果你忘了写它,很多 POST 提交会直接失败。

零基础阶段你先记住:

  • 表单 POST 提交时基本都要写
  • 这是 Django 的安全机制

表单层在真实项目中的常见场景

它特别适合这些页面:

  • 登录页
  • 注册页
  • 修改密码页
  • 搜索页
  • 资料填写页

也就是说,只要页面涉及“用户输入并提交”,Form 层就通常有价值。

常见错误

1. 没调用 is_valid() 就直接取 cleaned_data

这会导致逻辑不安全,也不符合表单使用流程。

2. 忘记在模板中写 {% csrf_token %}

很多 POST 表单提交失败都和这个有关。

3. 表单类定义了字段,但视图没把 POST 数据传进去

正确写法应该是:

python
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 登录、注册、资料填写这些页面时,就会有很清晰的套路。

Built with VitePress.