Django之form組件自動校驗數(shù)據(jù)實現(xiàn)
一、form介紹
我們之前在HTML頁面中利用form表單向后端提交數(shù)據(jù)時,都會寫一些獲取用戶輸入的標(biāo)簽并且用form標(biāo)簽把它們包起來。
與此同時我們在好多場景下都需要對用戶的輸入做校驗,比如校驗用戶是否輸入,輸入的長度和格式等正不正確。如果用戶輸入的內(nèi)容有錯誤就需要在頁面上相應(yīng)的位置顯示對應(yīng)的錯誤信息.。
Django form組件就實現(xiàn)了上面所述的功能。
總結(jié)一下,其實form組件的主要功能如下:
- 生成頁面可用的HTML標(biāo)簽
- 對用戶提交的數(shù)據(jù)進(jìn)行校驗
- 保留上次輸入內(nèi)容
二、普通方式手寫注冊功能
views.py
# 注冊
def register(request):
error_msg = ""
if request.method == "POST":
username = request.POST.get("name")
pwd = request.POST.get("pwd")
# 對注冊信息做校驗
if len(username) < 6:
# 用戶長度小于6位
error_msg = "用戶名長度不能小于6位"
else:
# 將用戶名和密碼存到數(shù)據(jù)庫
return HttpResponse("注冊成功")
return render(request, "register.html", {"error_msg": error_msg})
register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注冊頁面</title>
</head>
<body>
<form action="/reg/" method="post">
{% csrf_token %}
<p>
用戶名:
<input type="text" name="name">
</p>
<p>
密碼:
<input type="password" name="pwd">
</p>
<p>
<input type="submit" value="注冊">
<p style="color: red">{{ error_msg }}</p>
</p>
</form>
</body>
</html>
三、使用form組件實現(xiàn)注冊功能
views.py
先定義好一個RegForm類:
from django import forms # 按照Django form組件的要求自己寫一個類 class RegForm(forms.Form): name = forms.CharField(label="用戶名") pwd = forms.CharField(label="密碼")
再寫一個視圖函數(shù):
# 使用form組件實現(xiàn)注冊方式
def register2(request):
form_obj = RegForm()
if request.method == "POST":
# 實例化form對象的時候,把post提交過來的數(shù)據(jù)直接傳進(jìn)去
form_obj = RegForm(request.POST)
# 調(diào)用form_obj校驗數(shù)據(jù)的方法
if form_obj.is_valid():
return HttpResponse("注冊成功")
return render(request, "register2.html", {"form_obj": form_obj})
register2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注冊2</title>
</head>
<body>
<form action="/reg2/" method="post" novalidate autocomplete="off">
{% csrf_token %}
<div>
<label for="{{ form_obj.name.id_for_label }}">{{ form_obj.name.label }}</label>
{{ form_obj.name }} {{ form_obj.name.errors.0 }}
</div>
<div>
<label for="{{ form_obj.pwd.id_for_label }}">{{ form_obj.pwd.label }}</label>
{{ form_obj.pwd }} {{ form_obj.pwd.errors.0 }}
</div>
<div>
<input type="submit" class="btn btn-success" value="注冊">
</div>
</form>
</body>
</html>
看網(wǎng)頁效果發(fā)現(xiàn) 也驗證了form的功能:
- 前端頁面是form類的對象生成的 -->生成HTML標(biāo)簽功能
- 當(dāng)用戶名和密碼輸入為空或輸錯之后 頁面都會提示 -->用戶提交校驗功能
- 當(dāng)用戶輸錯之后 再次輸入 上次的內(nèi)容還保留在input框 -->保留上次輸入內(nèi)容
四、pycharm的專屬測試環(huán)境
1.使用方法
1.導(dǎo)入要測試的py文件
2.生成一個對象


2.本地校驗測試的一些參數(shù)
from_obj.is_valid() //判斷校驗是否通過
from_obj.cleaned_data //拿到當(dāng)前符號校驗的數(shù)據(jù){'username': '111', 'password': '111'}
form_obj.errors //拿到當(dāng)前校驗不通過的數(shù)據(jù)
少傳參數(shù)Flalse,多傳Trun。因為少傳了拿不到校驗的數(shù)據(jù),多傳了也不會使用。這是字典的形式
五、html自動生成input用戶輸入框的三種方式
forms組件只幫你渲染獲取用戶輸入(輸入 選擇 下拉 文件)的標(biāo)簽 不渲染按鈕和form表單標(biāo)簽
渲染出來的每一個input提示信息都是類中字段首字母大寫
class MyRegForm(forms.Form):
username = forms.CharField(max_length=8, min_length=3) # 最長8位,最短3位
password = forms.CharField(max_length=8, min_length=3) # 最長8位,最短3位
email = forms.EmailField() # 郵箱驗證
def reg(request):
# 1 先生成一個空的類對象
form_obj = MyRegForm()
if request.method == 'POST':
# 3 獲取用戶數(shù)據(jù)并交給forms組件校驗 request.POST
form_obj = MyRegForm(request.POST)
# 4 獲取校驗結(jié)果
if form_obj.is_valid():
return HttpResponse('數(shù)據(jù)沒問題')
else:
# 5 獲取校驗失敗的字段和提示信息
print(form_obj.errors)
# 2 直接將該對象傳給前端頁面
return render(request, 'reg.html', locals())
第一種方式 {{ form_obj.as_p }} (不推薦)
不推薦,封裝程度高,擴(kuò)展性低。一般測試本地用
<body>
<p>第一種渲染方式:多個p標(biāo)簽 本地測試方便 封裝程度太高了 不便于擴(kuò)展</p>
{{ form_obj.as_p }}
{#{{ form_obj.as_ul }}#}
{#{{ form_obj.as_table }}#}
</body>

第二種方式 {{ form_obj.username }} (不推薦)
不推薦,擴(kuò)展性較高 ,書寫較為繁瑣,每一個input框都需要自己手動寫
<p>第二種渲染方式: 擴(kuò)展性較高 書寫較為繁瑣</p>
<label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>
{{ form_obj.username }}
{{ form_obj.password.label }}{{ form_obj.password }}
{{ form_obj.email.label }}{{ form_obj.email }}

第三種方式 for循環(huán) (推薦)
推薦使用,for循環(huán)方式
{{ form.errors.0 }} # 這個是模板語法
<p>第三種渲染方式 推薦使用</p>
<form action="" method="post" novalidate>
{% for form in form_obj %}
<p>
{{ form.label }}{{ form }}
<span>{{ form.errors.0 }}</span>
</p>
{% endfor %}
<input type="submit">
</form>


六、數(shù)據(jù)校驗
*******數(shù)據(jù)校驗一個前后端都得有 但是前端的校驗弱不禁風(fēng) 可有可無
而后端的校驗則必須非常全面
如何取消瀏覽器自動幫我們校驗的功能?
在form后加參數(shù) no validate,不驗證
form表單取消前端瀏覽器自動校驗功能 <form action="" method="post" novalidate>

常用校驗參數(shù)
max_length //允許輸入的最大長度
min_length //最小長度
label input的提示信息,name、password等
error_messages 自定義報錯的提示信息
'max_length':"用戶名最長8位",
'min_length':"用戶名最短3位",
'required':"用戶名不能為空"
required 設(shè)置字段是否允許為空
initial 設(shè)置默認(rèn)值
widget 控制type類型及屬性
使用方式
CharField用戶名類型校驗
from django.forms import widgets //不導(dǎo)入也可以,沒提示
class MyRegForm(forms.Form):
# 用戶名最少3位最多8位
username = forms.CharField(max_length=8,min_length=3,label='用戶名',
error_messages={ //報錯信息的提示
'max_length':"用戶名最長8位",
'min_length':"用戶名最短3位",
'required':"用戶名不能為空"
},required=False,initial='jeff', // 為空和默認(rèn)值
widget=forms.widgets.TextInput(attrs={'class':'form-control c1 c2'}), //設(shè)置input的type屬性為text,及class屬性
)

password校驗
class LoginForm(forms.Form):
...
pwd = forms.CharField(
min_length=6,
label="密碼",
widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
)
郵箱類型校驗
class MyRegForm(forms.Form):
# email字段必須填寫符合郵箱格式的數(shù)據(jù)
email = forms.EmailField(label='郵箱',error_messages={
'required':'郵箱必填',
'invalid':'郵箱格式不正確'
})

手機(jī)號類型校驗
正則匹配
from django.core.validators import RegexValidator
class MyRegForm(forms.Form):
# 手機(jī)號
phone = forms.CharField(
validators=[
RegexValidator(r'^[0-9]+$', '請輸入數(shù)字'),
RegexValidator(r'^159[0-9]+$', '數(shù)字必須以159開頭')
]
)

性別校驗
gender = forms.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性別",
initial=3,
widget=forms.widgets.RadioSelect()
)
愛好單選 select校驗
hobby = forms.ChoiceField(
choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
label="愛好",
initial=3,
widget=forms.widgets.Select() # 單選
)

愛好多選select 校驗1
hobby1 = forms.MultipleChoiceField(
choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
label="愛好",
initial=[1, 3],
widget=forms.widgets.SelectMultiple()
)

愛好多選chekbox校驗2
hobby2 = forms.MultipleChoiceField(
choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
label="愛好",
initial=[1, 3],
widget=forms.widgets.CheckboxSelectMultiple()
)

是否記住密碼校驗
keep = forms.ChoiceField(
label="是否記住密碼",
initial="checked",
widget=forms.widgets.CheckboxInput()
)

七、鉤子函數(shù)
# 如果你想同時操作多個字段的數(shù)據(jù)你就用全局鉤子
# 如果你想操作單個字段的數(shù)據(jù) 你就用局部鉤子
鉤子勾回來處理完之后,還要還回去的
局部鉤子
校驗用戶名中不能包含666
# 局部鉤子
# 這里的self是自己類,MyRegForm
def clean_username(self):
username = self.cleaned_data.get('username')
if '666' in username:
self.add_error('username','光喊666是不行的')
return username
全局鉤子
兩次密碼驗證
class MyRegForm(forms.Form):
# 密碼
password = forms.CharField(max_length=8,min_length=3,label='密碼',
widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})
)
# 密碼驗證
re_password = forms.CharField(max_length=8,min_length=3,label='確認(rèn)密碼',
widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})
)
def clean(self):
# 這里的self是自己類,MyRegForm
# 校驗密碼和確認(rèn)密碼是否一致
password = self.cleaned_data.get('password')
re_password = self.cleaned_data.get('confirm_password')
if not password == re_password:
# 展示提示信息
self.add_error('re_password','兩次密碼不一致')
return self.cleaned_data

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python無限生成不重復(fù)(字母,數(shù)字,字符)組合的方法
今天小編就為大家分享一篇python無限生成不重復(fù)(字母,數(shù)字,字符)組合的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12
Python numpy數(shù)組轉(zhuǎn)置與軸變換
這篇文章主要介紹了Python numpy數(shù)組轉(zhuǎn)置與軸變換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11
以Python的Pyspider為例剖析搜索引擎的網(wǎng)絡(luò)爬蟲實現(xiàn)方法
這篇文章主要介紹了以Python的Pyspider為例剖析搜索引擎的網(wǎng)絡(luò)爬蟲實現(xiàn)方法,Pyspider是一個開源項目、用Python語言編寫十分簡潔且具有爬蟲程序的代表性,需要的朋友可以參考下2015-03-03
Python存儲List數(shù)據(jù)到文件(text/csv/excel)幾種常見方法
在數(shù)據(jù)分析中經(jīng)常需要從csv格式的文件中存取數(shù)據(jù)以及將數(shù)據(jù)寫書到csv文件中,下面這篇文章主要給大家介紹了關(guān)于Python存儲List數(shù)據(jù)到文件(text/csv/excel)的幾種常見方法,需要的朋友可以參考下2024-02-02
Python sklearn CountVectorizer使用詳解
這篇文章主要介紹了Python_sklearn_CountVectorizer使用詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03
Python解決兩個整數(shù)相除只得到整數(shù)部分的實例
今天小編就為大家分享一篇Python解決兩個整數(shù)相除只得到整數(shù)部分的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11
在Python中字典根據(jù)多項規(guī)則排序的方法
今天小編就為大家分享一篇在Python中字典根據(jù)多項規(guī)則排序的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01
Python3.7 版本 lxml 模塊無法導(dǎo)入etree 問題及解決方法
這篇文章主要介紹了Python3.7 版本 lxml 模塊無法導(dǎo)入etree 問題及解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01

