Python中使用django form表單驗(yàn)證的方法
一. django form表單驗(yàn)證引入
有時(shí)時(shí)候我們需要使用get,post,put等方式在前臺(tái)HTML頁(yè)面提交一些數(shù)據(jù)到后臺(tái)處理例 ;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Form</title>
</head>
<body>
<div>
<form action="url" method="post" enctype="multipart/form-data">{% csrf_token %}
<input type="text" name="username"/>
<input type="password" name="password"/>
<input type="submit" value="submit"/>
</form>
</div>
</body>
前端提交后臺(tái)獲取:
from django.shortcuts import render,HttpResponse,redirect
from app01 import models
def Login(request):
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
return HttpResponse("Hello,%s"%(username))
這樣就完成了基本的功能,基本上可以用了。
但是,如果用戶(hù)輸入并未按照要求(比如手機(jī)號(hào)要輸數(shù)據(jù)11位長(zhǎng)度,密碼的復(fù)雜度等),還有就是提交后再回來(lái)已經(jīng)輸入的數(shù)據(jù)也會(huì)沒(méi)了
當(dāng)然如果我們手動(dòng)將輸入之后的數(shù)據(jù)在 views 中都獲取到再傳遞到網(wǎng)頁(yè),這樣是可行的,但是很不方便,所以 Django 提供了更簡(jiǎn)單易用的 forms 來(lái)解決驗(yàn)證等這一系列的問(wèn)題
,在這里不得不提Django的插件庫(kù)真的很強(qiáng)大,簡(jiǎn)單易擴(kuò)展,上面的內(nèi)容只是引進(jìn)為什么要使用form,下面著重記錄django form的使用
二.form表單驗(yàn)證應(yīng)用
需要在django的APP中新建一個(gè)模塊form.py,具體內(nèi)容如下
class RegisterForm(forms.Form):
email = forms.EmailField(required=True,
error_messages={'required': "郵箱不能為空"})
password = forms.CharField(max_length=120,
min_length=6,
required=True,
error_messages={'required': "密碼不能為空"})
invite_code = forms.CharField(required=True,error_messages={'required': "驗(yàn)證碼不能為空"})
前端頁(yè)面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>register</title>
</head>
<body>
<div>
<form action="url" method="post" enctype="multipart/form-data">
<input type="text" name="username"/>
<input type="password" name="password"/>
<input type="text" name="code"/>
<input type="submit" value="submit"/>
</form>
</div>
</body>
后臺(tái)views處理
def register(request):
if request.method == "POST":
f = Reg_Form(request.POST)
if f.is_valid():
user = f.cleaned_data["username"]
pwd = f.cleaned_data["password"]
code = f.cleaned_data["code"]
res_code = request.session.get("code", None)
result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd)
if code.upper() == res_code.upper() and result:
models.UserInfo.objects.filter(user__exact=user).update(status=1)
request.session["user"] = user
return redirect("/home")
else:
return render(request, "register.html", {"error": f.errors, "form": f})else:return render(request, "register.html")
Reg_Form(request.POST) 使用form類(lèi)來(lái)處理提交的數(shù)據(jù)來(lái)驗(yàn)證數(shù)據(jù)的合法性,is_valid()合法后的邏輯處理,驗(yàn)證后的數(shù)據(jù)保存在實(shí)例化后返回的cleaned_data中,
cleaned_data是個(gè)字典的數(shù)據(jù)格式,錯(cuò)誤信息保存在form.errors中比如說(shuō)想在views中查看所有報(bào)錯(cuò)信息print(f.errors),如果只想看用戶(hù)的可以
print(form.errors['username'][0])
錯(cuò)誤信息我們可以通過(guò) 模板渲染回前端頁(yè)面,例
<form action="/form/" method="POST">
{% csrf_token %}
<div class="input-group">
{#接收后臺(tái)傳過(guò)來(lái)的form對(duì)象,自動(dòng)生成input標(biāo)簽#}
{{ form.user }}
{#從后臺(tái)傳過(guò)來(lái)的error是字典,直接{{ error.user.0 }}呈現(xiàn)錯(cuò)誤信息#}
{#如果后臺(tái)返回了錯(cuò)誤信息,將錯(cuò)誤信息放入span標(biāo)簽,在頁(yè)面顯示,否則不顯示#}
{% if error.username.0 %}
<span>{{ error.userusername.0 }}</span>
{% endif %}
</div>
<div class="input-group">
{{ form.password }}
{% if error.pwd.0 %}
<span>{{ error.password .0 }}</span>
{% endif %}
</div>
<div>
<input type="submit" value="提交" />
</div>
</form>
三.自生成input框
Form類(lèi)
class RegisterForm(forms.Form):
style = 'form-control input-lg'
phone = forms.CharField(widget=forms.TextInput(attrs={'class': style,
'name': 'title'})),
required=True,
error_messages={'required': ugettext_lazy('*Required')})
code = forms.CharField(widget=forms.NumberInput(attrs={'placeholder': '驗(yàn)證碼',
'class': style}),
min_length=4,
max_length=4,
required=True,
error_messages={'required': ugettext_lazy('*Required')})
password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': '請(qǐng)輸入密碼',
'class': style}),
min_length=6,
required=True,
error_messages={'required': ugettext_lazy('*Required')})
views
def register(request):
if request.method == "POST":
f = RegisterForm(request.POST)
if f.is_valid():
user = f.cleaned_data["username"]
pwd = f.cleaned_data["password"]
code = f.cleaned_data["code"]
res_code = request.session.get("CheckCode", None)
result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd)
if code.upper() == res_code.upper() and result:
models.UserInfo.objects.filter(user__exact=user).update(status=1)
request.session["user"] = user
return redirect("/home")
else:
return render(request, "login.html", {"error": f.errors, "form": f})
else:
return render(request, "login.html", {"error": f.errors, "form": f})
else:
# 如果不是post提交數(shù)據(jù),就不傳參數(shù)創(chuàng)建對(duì)象,并將對(duì)象返回給前臺(tái),直接生成input標(biāo)簽,內(nèi)容為空
f = Log_Form()
return render(request, "login.html", {"form": f})
前端頁(yè)面
<body>
<form action="/form/" method="POST">
{% csrf_token %}
<div class="input-group">
{# 接收后臺(tái)傳過(guò)來(lái)的form對(duì)象,自動(dòng)生成input標(biāo)簽#}
{{ form.user }}
{# 從后臺(tái)傳過(guò)來(lái)的error是字典,直接{{ error.user.0 }}呈現(xiàn)錯(cuò)誤信息#}
{# 如果后臺(tái)返回了錯(cuò)誤信息,將錯(cuò)誤信息放入span標(biāo)簽,在頁(yè)面顯示,否則不顯示#}
<div class="input-group">
{{ form.email }}
{% if error.email.0 %}
<span>{{ error.email.0 }}</span>
{% endif %}
</div>
<div class="input-group">
{{ form.password }}
{% if error.password.0 %}
<span>{{ error.password.0 }}</span>
{% endif %}
</div>
<div class="input-group">
{{ form.code }}
{% if error.book_type.0 %}
<span>{{ error.code.0 }}</span>
{% endif %}
</div>
<div>
<input type="submit" value="提交" />
</div>
</form>
</body>
</html>
四.Form驗(yàn)證完善
https://docs.djangoproject.com/en/dev/ref/forms/validation/
form驗(yàn)證的運(yùn)行順序是init,clean,validte,save
其中clean和validate會(huì)在form.is_valid()方法中被先后調(diào)用
clean等步驟遇到的異常:Exception Value: argument of type 'NoneType' is not iterable.
可能是cleaned_data中某個(gè)字段值應(yīng)該是個(gè)列表,實(shí)際上卻是空值。
clean方法重寫(xiě)時(shí)一定不要忘了return cleaned_data
這樣重寫(xiě)可以使用戶(hù)提交的數(shù)據(jù)在form類(lèi)中執(zhí)行檢測(cè)完后返回?cái)?shù)據(jù)給用戶(hù),數(shù)據(jù)合法后進(jìn)行邏輯處理,不需要再進(jìn)行處理返回用戶(hù),更方便更合理
補(bǔ)充:
5.form的四種初始化方式
①實(shí)例化oneform(initial={'onefield':value})
②定義字段時(shí)給初始化值oneformfield = forms.CharField(initial=value)
③重寫(xiě)Form類(lèi)的__init__()方法:self.fields['onefield'].initial = value
④當(dāng)給form傳參instanse(即oneform(instanse=onemodel_instance))時(shí),前三種初始化方法會(huì)全部失效,即使重寫(xiě)__init__時(shí),先調(diào)用父類(lèi)的__init__再使用方法③,仍然無(wú)效(不是很爽)。
這時(shí)想重新初始化字段值只能在__init__()里 self.initial['title'] = value,直接對(duì)Form類(lèi)的initial屬性字典賦值。
from django import forms
class RegisterForm(forms.Form):
email = forms.EmailField(required=True,
error_messages={'required': "郵箱不能為空"})
password = forms.CharField(max_length=120,
min_length=6,
required=True,
error_messages={'required': "密碼不能為空"})
invite_code = forms.CharField(required=True,error_messages={'required': "驗(yàn)證碼不能為空"})
def clean(self):
# 用戶(hù)名
try:
email = self.cleaned_data['email']
except Exception as e:
raise forms.ValidationError(u"注冊(cè)賬號(hào)需為郵箱格式")
# 驗(yàn)證郵箱
user = User.objects.filter(username=email)
if user: # 郵箱已經(jīng)被注冊(cè)了
raise forms.ValidationError(u"郵箱已被注冊(cè)")
# 密碼
try:
password = self.cleaned_data['password']
except Exception as e:
print('except: ' + str(e))
raise forms.ValidationError(u"請(qǐng)輸入至少6位密碼")
return self.cleaned_data
以上所述是小編給大家介紹的Python中使用django form表單驗(yàn)證的方法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
golang實(shí)現(xiàn)php里的serialize()和unserialize()序列和反序列方法詳解
這篇文章主要介紹了golang實(shí)現(xiàn)php里的serialize()和unserialize()序列和反序列方法詳解,需要的朋友可以參考下2018-10-10
函數(shù)中使用require_once問(wèn)題深入探討 優(yōu)雅的配置文件定義方法推薦
這篇文章主要介紹了函數(shù)中使用require_once問(wèn)題深入探討,優(yōu)雅的配置文件定義方法推薦,最終用一個(gè)靜態(tài)類(lèi)來(lái)定義配置文件獲勝,完美解決函數(shù)中使用require_once的問(wèn)題,需要的朋友可以參考下2014-07-07

