Django Form 元件用于對頁面進行初始化,生成 HTML 标簽,此外還可以對使用者送出對資料進行校驗(顯示錯誤資訊)。
報錯資訊顯示順序:
先顯示字段屬性中的錯誤資訊,然後再顯示局部鈎子的錯誤資訊。
若顯示了字段屬性的錯誤資訊,就不會顯示局部鈎子的錯誤資訊。
若有全局鈎子,則全局鈎子是等所有的資料都校驗完,才開始進行校驗,并且全局鈎子的錯誤資訊一定會顯示。
使用 Form 元件,需要先導入 forms:

接下來我們在 app01 目錄下建立一個 My_forms.py:
from django import forms
from django.core.exceptions import ValidationError
from app01 import models
class EmpForm(forms.Form):
name = forms.CharField(min_length=4, label="姓名", error_messages={"min_length": "你太短了", "required": "該字段不能為空!"})
age = forms.IntegerField(label="年齡")
salary = forms.DecimalField(label="工資")
字段屬性:
label:輸入框前面的文本資訊。
error_message:自定義顯示的錯誤資訊,屬性值是字典, 其中 required 為設定不能為空時顯示的錯誤資訊的 key。
from django.shortcuts import render, HttpResponse
from app01.My_Forms import EmpForm
# Create your views here.
def add_emp(request):
if request.method == "GET":
form = EmpForm()
return render(request, "add_emp.html", {"form": form})
else:
form = EmpForm(request.POST)
if form.is_valid(): # 進行資料校驗
# 校驗成功
data = form.cleaned_data # 校驗成功的值,會放在cleaned_data裡。
data.pop('r_salary')
print(data)
models.Emp.objects.create(**data)
return HttpResponse(
'ok'
)
# return render(request, "add_emp.html", {"form": form})
else:
print(form.errors) # 列印錯誤資訊
clean_errors = form.errors.get("__all__")
print(222, clean_errors)
return render(request, "add_emp.html", {"form": form, "clean_errors": clean_errors})
app01/urls.py 檔案添加以下規則:
HTML 模版:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h3>添加員工</h3>
{#1、自己手動寫HTML頁面#}
<form action="" method="post">
<p>姓名:<input type="text" name="name"></p>
<p>年齡:<input type="text" name="age"></p>
<p>工資:<input type="text" name="salary"></p>
<input type="submit">
</form>
{#2、通過form對象的as_p方法實作#}
{#<form action="" method="post" novalidate>#}
{# {% csrf_token %}#}
{# {{ form.as_p }}#}
{# <input type="submit">#}
{#</form>#}
{#3、手動擷取form對象的字段#}
{# <div>#}
{# <label for="id_{{ form.name.name }}">姓名</label>#}
{# {{ form.name }} <span>{{ form.name.errors.0 }}</span>#}
{# </div>#}
{# <label for="id_{{ form.age.name }}">年齡</label>#}
{# {{ form.age }} <span>{{ form.age.errors.0 }}</span>#}
{# <label for="id_salary">工資</label>#}
{# {{ form.salary }} <span>{{ form.salary.errors.0 }}</span>#}
{#4、用for循環展示所有字段#}
{# {% for field in form %}#}
{# <div>#}
{# <label for="id_{{ field.name }}">{{ field.label }}</label>#}
{# {{ field }} <span>{{ field.errors.0 }}</span>#}
{# </div>#}
{# {% endfor %}#}
</body>
</html>
運作結果如下圖所示:
定義 Form 類:
name = forms.CharField(min_length=5, label="姓名", error_messages={"required": "該字段不能為空!",
"min_length": "使用者名太短。"})
salary = forms.DecimalField(max_digits=5, decimal_places=2, label="工資")
r_salary = forms.DecimalField(max_digits=5, decimal_places=2, label="請再輸入工資")
def clean_name(self): # 局部鈎子
val = self.cleaned_data.get("name")
if val.isdigit():
raise ValidationError("使用者名不能是純數字")
elif models.Emp.objects.filter(name=val):
raise ValidationError("使用者名已存在!")
return val
def clean(self): # 全局鈎子 确認兩次輸入的工資是否一緻。
val = self.cleaned_data.get("salary")
r_val = self.cleaned_data.get("r_salary")
if val == r_val:
return self.cleaned_data
raise ValidationError("請确認工資是否一緻。")
views.py 檔案代碼:
form = EmpForm() # 初始化form對象
return render(request, "add_emp.html", {"form":form})
form = EmpForm(request.POST) # 将資料傳給form對象
if form.is_valid(): # 進行校驗
data = form.cleaned_data
data.pop("r_salary")
return redirect("/index/")
else: # 校驗失敗
clear_errors = form.errors.get("__all__") # 擷取全局鈎子錯誤資訊
return render(request, "add_emp.html", {"form": form, "clear_errors": clear_errors})
模闆檔案代碼如下:
<form action="" method="post" novalidate>
{% csrf_token %}
<div>
<label for="id_{{ form.name.name }}">姓名</label>
{{ form.name }} <span>{{ form.name.errors.0 }}</span>
</div>
<label for="id_{{ form.age.name }}">年齡</label>
{{ form.age }} <span>{{ form.age.errors.0 }}</span>
<label for="id_salary">工資</label>
{{ form.salary }} <span>{{ form.salary.errors.0 }}{{ clear_errors.0 }}</span>
<label for="id_r_salary">請再輸入工資</label>
{{ form.r_salary }} <span>{{ form.r_salary.errors.0 }}{{ clear_errors.0 }}</span>