HTML 表单谁都能写,但 Django 的强项在于:
表单结构、服务端校验、错误回显、模型绑定,能走成一条完整流程。
先写一个 ModelForm:
from django import forms
from .models import Permit
class PermitForm(forms.ModelForm):
class Meta:
model = Permit
fields = ["title", "department", "description"]
def clean_title(self):
title = self.cleaned_data["title"].strip()
if len(title) < 4:
raise forms.ValidationError("事项标题至少 4 个字符")
return title再写创建视图:
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect, render
from .forms import PermitForm
@login_required
def create(request):
if request.method == "POST":
form = PermitForm(request.POST)
if form.is_valid():
permit = form.save(commit=False)
permit.created_by = request.user
permit.save()
return redirect("permits:detail", pk=permit.pk)
else:
form = PermitForm()
return render(request, "permits/form.html", {"form": form})模板:
<!-- templates/permits/form.html -->
{% extends "base.html" %}
{% block content %}
<h2>新建许可证申请</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">提交申请</button>
</form>
{% endblock %}表单处理流程图:
GET /permits/create/
│
▼
显示空白表单
│
▼
用户填写并 POST
│
▼
form = PermitForm(request.POST)
│
▼
form.is_valid()
├── 否:回显错误
└── 是:保存数据
│
▼
redirect 到详情页这里有三个必须形成肌肉记忆的点。
第一,{% csrf_token %} 不是装饰品,是防跨站请求伪造的重要机制。
第二,成功提交后通常走 POST / Redirect / GET,不要直接在 POST 成功后原地渲染成功页,否则刷新容易重复提交。
第三,表单校验一定要以服务端为准。前端校验可以提升体验,但不能替代 Django 表单或模型层的校验。