Django Forms元件,展示使用者輸入不合規的提示資訊,鉤子函式
前戲:使用form表單,使用者輸入特定資訊,比如:金瓶,輸入框右側提示資訊,不使用Ajax。
前端程式碼:
<body>
<form action="" method="post">
<p>username: <input type="text" name="username">
<!--get請求觸發是,字典為空,span是行內標籤,行內標籤特性文字帶下取決於內部文字,此時不佔任何空間-->
<span style="font-size: 15px">{{ back_dict.username }}</span>
</p>
<p>password: <input type="text" name="password">
<span style="font-size: 15px">{{ back_dict.password }}</span>
</p>
<input type="submit" class="btn btn-danger">
</form>
</body>
後端程式碼邏輯:
def pl(request):
back_dict = {'username': '', 'password': ''}
"""
首先無論是POST還是GET請求,頁面都可獲得back_dict自定義字典
只不過get請求來的時候,字典值是空的
而post請求來之後,字典可能有值
"""
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if '金瓶' in username:
back_dict['username'] = '違規用詞'
if len(password) < 3:
back_dict['password'] = '密碼不可低於三位數'
return render(request, 'pl.html', locals())
以上使用到的技術點。
- 手動書寫前端獲取使用者資料的html程式碼 ---渲染html程式碼
- 後端對使用者資料進行校驗 ---校驗資料
- 對不符合要求的資料進行前端提示 ---展示提示資訊
然而,form元件恰好也你能為我們做這些事。
注意: 資料校驗前端可有可無,但是後端一定要有,前後端結合校驗更好。
forms元件功能
- 渲染html程式碼
- 校驗資料
- 展示提示資訊
forms基本使用
匯入模組,並自定義類。
from django import forms
class MyForm(forms.Form):
# username欄位串型別最小3位,最大8位
username = forms.CharField(min_length=3,max_length=8)
# password欄位串型別最小3位,最大8位
password = forms.CharField(min_length=3,max_length=8)
# 郵箱欄位必須符合郵箱格式
email = forms.EmailField()
校驗資料
- 測試環境,test.py,自己複製程式碼準備
- Pycharm自帶校驗資料功能
方法 描述
.is_valid() 判斷資料是否合法
.cleaned_data 檢視校驗透過資料
.errors 檢視未透過資料以及未透過原因
froms元件校驗資料只校驗類中出現的欄位,多傳不影響,多傳的欄位直接忽略
form_obj = views.MyForm({'username':'junjie','password':'123','email':'123@qq.com'})
form_obj.is_valid()
True
form_obj = views.MyForm({'username':'junjie','password':'123','email':'123@qq.com','like':'play'})
form_obj.is_valid()
True
form_obj.cleaned_data
{'username': 'junjie', 'password': '123', 'email': '123@qq.com'}
froms元件校驗資料 預設情況下,類中的所有欄位都必須傳值。
form_obj = views.MyForm({'username':'junjie','password':'123'})
form_obj.is_valid()
False
form_obj.cleaned_data
{'username': 'junjie', 'password': '123'}
form_obj.errors
{'email': ['This field is required.']}
渲染html
forms元件只會自動渲染獲取使用者輸入的標籤(input,select,radio,checkbox)
第一種方式
封裝程度太高,只適合本地測試使用。
views.py
from django import forms
class MyForm(forms.Form):
# username欄位串型別最小3位,最大8位
username = forms.CharField(min_length=3,max_length=8)
# password欄位串型別最小3位,最大8位
password = forms.CharField(min_length=3,max_length=8)
# 郵箱欄位必須符合郵箱格式
email = forms.EmailField()
def index(request):
# 先產生一個空物件,空物件是關鍵
form_obj = MyForm()
# 直接將該空物件傳遞給html頁面
return render(request,'index.html',locals())
前端
<form action="" method="post">
<p>第一種渲染方式</p>
<!--樣式多,但是封裝程度太高,適合本地測試-->
{{ form_obj.as_p }}
{{ form_obj.as_ul }}
{{ form_obj.as_table }}
</form>
擴充套件性高,但是書寫程式碼過多,一般不用
<form action="" method="post">
<p>第二種渲染方式</p>
<p>{{ form_obj.username.label }}: {{ form_obj.username }}</p>
<p>{{ form_obj.password.label }}: {{ form_obj.password }}</p>
<p>{{ form_obj.email }}: {{ form_obj.email.label }}</p>
</form>
第三種渲染方式,推薦使用
<p>第三種渲染方式</p>
{% for form in form_obj %}
<p>{{ form.label }}: {{ form }}</p>
{% endfor %}
<p></p>
總結:label屬性預設展示的是類中定義的欄位首字母與大寫的形式,也可以自己修改,直接給欄位物件加label屬性即可。
展示使用者輸入不合規的提示資訊
瀏覽器會自動校驗資料,但是前端的校驗弱不禁風,檢查中可以更改型別,那麼如何讓瀏覽器不做校驗由後端來做校驗?
<!--novalidate 告知前端不做校驗-->
<form action="" method="post" novalidate>
</form>
![](https://img2024.cnblogs.com/blog/1223896/202403/1223896-20240325085401845-612882431.png)
<form action="" method="post" novalidate>
<p>第三種渲染方式</p>
{% for form in form_obj %}
<p>{{ form.label }}: {{ form }}</p>
<!--{{ form.errors.0 }} 意味著這拿列表中第一個錯誤資訊,並且也不會生成ul標籤-->
<span style="color: red">{{ form.errors.0 }}</span>
{% endfor %}
<input type="submit" class="btn btn-danger">
</form>
此時input輸入框最多輸入也被限制,並且點選提交按鈕,頁面重新整理但是input輸入框中的資訊也不會被重新整理,原由還是form元件的特殊之處,那麼為什麼會如此?
檢視後端邏輯程式碼。
def index(request):
# 先產生一個空物件,空物件是關鍵
form_obj = MyForm()
if request.method == 'POST':
# 獲取使用者資料並校驗
"""
1.資料獲取繁瑣
2.校驗資料需要構造成字典的格式傳入才可以
ps:但是request.POST 可以看成一個字典
"""
form_obj = MyForm(request.POST)
# 判斷資料是否合法
if form_obj.is_valid():
# 合法運算元據庫,儲存資料
return HttpResponse('恭喜,輸入資料全都合規')
# 不合法 有錯誤
# else:
# 如何將錯誤資訊展示到前端?
# 直接將該空物件傳遞給html頁面
return render(request, 'index.html', locals())
- forms元件展示錯物資訊必備的條件:
- get請求和post請求傳給html頁面的物件變數名必須一樣
forms元件當你的資料不合法的情況下,會儲存上次輸入的資料,讓你基於之前的結果進行修改,更加人性化
到此forms元件錯誤資訊介紹完畢,接下補充知識。
方法 描述
label 欄位名
error_messages 自定義報錯資訊
initial 預設值
required forms元件中所有欄位預設必填(required)
required預設為Ture,可改為False
控制欄位是否必填
widget 更改input的type型別,以及增加bootstrap樣式
ValidationError 正則校驗,需要匯入模組
radio 單選框
Select 下拉框
checkbox 多選框
ValidationError,forms元件正則校驗,自上而下校驗。
from django.core.validators import RegexValidator
舉例ValidationError:
phone = forms.CharField(
validators=[
RegexValidator(r'^[0-9]+$', '請輸入數字'), # 先校驗這個正則,透過再校驗下面這個正則
RegexValidator(r'^159[0-9]+$', '數字必須以159開頭')
]
)
後端邏輯程式碼error_messages:
from django import forms
class MyForm(forms.Form):
# username欄位串型別最小3位,最大8位
username = forms.CharField(min_length=3, max_length=8, label='使用者名稱',
# 不合符提醒自定義資訊
error_messages={
'min_length=3':'使用者名稱最少3位',
'max_length':'使用者名稱最大8位',
# required沒有傳值
'required':'使用者名稱不能為空'
})
# password欄位串型別最小3位,最大8位
password = forms.CharField(min_length=3, max_length=8, label='密碼',
error_messages={
'min_length=3': '密碼最少3位',
'max_length': '密碼最大8位',
# required沒有傳值
'required': '密碼不能為空'
}
)
# 郵箱欄位必須符合郵箱格式
email = forms.EmailField(label='郵箱',
error_messages={
# 郵箱固定格式
'invalid':'郵箱格式不能為空',
# required沒有傳值
'required': '郵箱不能為空'
}
)
def index(request):
# 先產生一個空物件,空物件是關鍵
form_obj = MyForm()
if request.method == 'POST':
# 獲取使用者資料並校驗
"""
1.資料獲取繁瑣
2.校驗資料需要構造成字典的格式傳入才可以
ps:但是request.POST 可以看成一個字典
"""
form_obj = MyForm(request.POST)
# 判斷資料是否合法
if form_obj.is_valid():
# 合法運算元據庫,儲存資料
return HttpResponse('恭喜,輸入資料全都合規')
# 不合法 有錯誤
# else:
# 如何將錯誤資訊展示到前端?
# 直接將該空物件傳遞給html頁面
return render(request, 'index.html', locals())
舉例radio,select,checkbox
# radio 單選框
gender = forms.fields.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性別",
initial=3,
widget=forms.widgets.RadioSelect()
)
# select 單選下拉框
hobby1 = forms.ChoiceField(
choices=((1, "籃球"), (2, "足球"), (3, "雙色球"), ),
label="愛好",
initial=3,
widget=forms.widgets.Select()
)
# select 多選下拉框
hobby2 = forms.MultipleChoiceField(
choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
label="愛好",
initial=[1, 3],
widget=forms.widgets.SelectMultiple()
)
# 單選checkbox
keep = forms.ChoiceField(
label="是否記住密碼",
initial="checked",
widget=forms.widgets.CheckboxInput()
)
# 多選checkbox
hobby = forms.MultipleChoiceField(
choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
label="愛好",
initial=[1, 3],
widget=forms.widgets.CheckboxSelectMultiple()
)
鉤子函式(HOOK)
描述:在特點的節點自動觸發完成響應操作。在forms元件中類似於第二道關卡,讓我們自定義校驗規則。
在forms元件中有兩類鉤子:
- 區域性鉤子
當你需要給單個欄位增加校驗規則的時候可以使用 - 全域性鉤子
當你需要給多個欄位增加校驗規則的時候可以使用
第一道forms校驗透過會觸發自定義鉤子函式校驗 ,在類中定義。
舉例:
- 校驗使用者名稱中不能含有666 ---只校驗一個欄位,區域性鉤子
2.校驗密碼和確認密碼是否一致 ---校驗多個欄位,全域性鉤子
class MyForm(forms.Form):
username = forms.CharField(min_length=3, max_length=8, label='使用者名稱',
error_messages={'min_length': '最小三位數',
'max_length': '最大三位數',
'required': '不能為空'})
password = forms.CharField(min_length=3, max_length=8, label='密碼',
error_messages={
'min_length=3': '密碼最少3位',
'max_length': '密碼最大8位',
# required沒有傳值
'required': '密碼不能為空'
}
)
two_password = forms.CharField(min_length=3, max_length=8, label='二次確認密碼',
error_messages={
'min_length=3': '二次確認密碼最少3位',
'max_length': '二次確認密碼最大8位',
# required沒有傳值
'required': '二次確認密碼不能為空'
}
)
email = forms.EmailField(label='郵箱',
error_messages={
# 郵箱固定格式
'invalid': '郵箱格式不能為空',
# required沒有傳值
'required': '郵箱不能為空'
}
)
# 鉤子函式
# 區域性鉤子
def clean_username(self):
# 獲取到使用者名稱
username = self.cleaned_data.get('username')
if '666' in username:
# 提示前端展示錯誤資訊
self.add_error('username', '不能只有666')
# 將鉤子函式勾出來的資料再放回去
return username
# 全域性鉤子
def clean(self):
password = self.cleaned_data.get('password')
two_password = self.cleaned_data.get('two_password')
if two_password != password:
self.add_error('two_password','兩次密碼不一致')
# 將鉤子函式勾出來的資料再放回去
return self.cleaned_data