您的位置:首页 > 编程语言 > Go语言

Django 进阶篇之 Form验证

2016-09-12 14:31 387 查看

DjangoForm验证

在实际的生产环境中比如登录和验证的时候,我们一般都使用Jquery+ajax来判断用户的输入是否为空,假如JS被禁用的话,咱们这个认证屏障是不是就消失了呢?(虽然一般不会禁用掉但是还是存在风险)所以我们一般做两种认证一种是前端做一遍认证,在后端做一遍认证。

如果前端中要涉及到很多input,提交到后台,后台要一一取出,分别做验证,这是件很痛苦的事。

defregister(request):
ifrequest.method=="POST":
ret={"status":False,"msg":""}
u=request.POST.get('user',None)
e=request.POST.get('email',None)
p=request.POST.get('password',None)
p2=request.POST.get('password2',None)
#这里有个问题,如果,这个from表单有20个input,你在这里是不是的取20次?
count=models.UserInfo.objects.filter(user=u).count()
ifcount==0:
ifp==p2:
print("注册成功")
models.UserInfo.objects.create(user=u,email=e,password=p)
data_list=models.UserInfo.objects.all()
ret["status"]=True
ret["msg"]="注册成功,请登录"
returnHttpResponse(json.dumps(ret))
#returnredirect('/index/')
else:
print('diff')
ret["msg"]="两次输入密码不一致"
returnHttpResponse(json.dumps(ret))
eliflen(u)>0andcount>=1:
print('用户名已经存在')
ret["msg"]="用户名已经存在"
returnHttpResponse(json.dumps(ret))
else:
returnrender(request,'cmdb/register.html',)
#验证:
#输入不能为空,并且有的可以为空有的不可以为空
#如果email=xxxx这样合法吗
'''
你在这里是不是需要做一大堆的输入验证啊?并且有很多这种页面会存在这种情况,如果每个函数都这样做估计就累死了
'''

ifrequest.method=='GET':
returnrender(request,'cmdb/register.html',)


在样能解决这个问题呢?通过Django的form来实现,其他语言也有叫做(模型绑定)

Django的form的作用:

1、生成html标签

2、用来做用户提交的验证

1、生成html标签

views

fromdjangoimportforms
classLoginForm(forms.Form):
user=forms.CharField(required=True,error_messages={'required':'用户名不能为空.'})
pwd=forms.CharField(required=True,
min_length=6,
max_length=10,
error_messages={'required':'密码不能为空.','min_length':"至少6位"})

num=forms.IntegerField(error_messages={'required':'数字不能空.','invalid':'必须输入数字'})

phone=forms.CharField(validators=[mobile_validate,],)

test=forms.CharField(widget=forms.Textarea(attrs={'class':'c1'}))

deflogin(request):
ifrequest.POST:
objPost=LoginForm(request.POST)
ret=objPost.is_valid()
#print(objPost)
print(ret)
ifret:
print(objPost.clean())
else:
fromdjango.forms.utilsimportErrorDict
#print(type(obj.errors),obj.errors.as_json())
#obj1.errors
print(objPost.errors.as_json())
returnrender(request,'login.html',{'obj1':objPost})
else:
objGet=LoginForm()
returnrender(request,'login.html',{'obj1':objGet})


html

<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<title>Title</title>
<style>
.error-msg{
color:red;
}
</style>
</head>
</head>
<body>
<formaction="/app01/login/"method="POST">
<div>
<div>
{{obj1.user}}
{%ifobj1.errors.user%}
<spanclass="error-msg">{{obj1.errors.user.0}}</span>

{%endif%}
</div>
<div>
{{obj1.pwd}}
<spanclass="error-msg">{{obj1.errors.pwd.0}}</span>
</div>
<div>
{{obj1.num}}
<spanclass="error-msg">{{obj1.errors.num.0}}</span>
</div>
<div>
{{obj1.phone}}
<spanclass="error-msg">{{obj1.errors.phone.0}}</span>
</div>
<div>
{{obj1.test}}
<spanclass="error-msg">{{obj1.errors.test.0}}</span>

</div>
<inputtype="submit"value="提交">
</div>
</form>
</body>
</html>




2、简单的form表单验证用户输入的内容

deflogin(request):
ifrequest.POST:
#获取用户输入一句话就搞定
objPost=LoginForm(request.POST)
'''
咱们把post过来的数据当参数传给LoginForm咱们定义的这个类,LoginForm会自动会去你提交的数据
user/pwd/num/phone自动的封装到objPost里,封装到这个对象里我们就可以判断输入是否合法
'''
ret=objPost.is_valid()
#print(objPost)
print(ret)
ifret:
print(objPost.clean())
else:
fromdjango.forms.utilsimportErrorDict
#print(type(obj.errors),obj.errors.as_json())
#obj1.errors
print(objPost.errors.as_json())
returnrender(request,'login.html',{'obj1':objPost})#然后把对象传给html
else:
objGet=LoginForm()#创建了这个对象
returnrender(request,'login.html',{'obj1':objGet})
fromdjango.views.decorators.csrfimportcsrf_exempt,csrf_protect


当我们输入不合法的时候,(在创建类设置的需求)为空、或者不是email格式的时候!



这样在后端我们是不是就有一套验证的机制?就可以通过is_valid()来判断用户输入是否合法!如果不合法就把返回信息发送过去,如果合法获取数据操作即可!

捕获错误信息并返回

fromdjangoimportforms

classLoginForm(forms.Form):
user=forms.CharField(required=True,error_messages={'required':'用户名不能为空.'})
pwd=forms.CharField(required=True,
min_length=6,
max_length=10,
error_messages={'required':'密码不能为空.','min_length':"至少6位"})

num=forms.IntegerField(error_messages={'required':'数字不能空.','invalid':'必须输入数字'})

phone=forms.CharField(validators=[mobile_validate,],)

test=forms.CharField(widget=forms.Textarea(attrs={'class':'c1'}))

deflogin(request):
ifrequest.POST:
#获取用户输入一句话就搞定
objPost=LoginForm(request.POST)
'''
咱们把post过来的数据当参数传给LoginForm咱们定义的这个类,LoginForm会自动会去你提交的数据
user/pwd/num/phone自动的封装到objPost里,封装到这个对象里我们就可以判断输入是否合法
'''
ret=objPost.is_valid()
#print(objPost)
print(ret)
ifret:
print(objPost.clean())
#通过验证,获取提交的数据
'''
{'user':'asfd','num':1,'pwd':'dsafss','test':'32','phone':'13331525685'}
'''
else:
fromdjango.forms.utilsimportErrorDict
#print(type(obj.errors),obj.errors.as_json())
#obj1.errors
print(objPost.errors)
'''
<ulclass="errorlist"><li>phone<ulclass="errorlist"><li>手机号码格式错误</li></ul></li></ul>
'''
returnrender(request,'login.html',{'obj1':objPost})#然后把对象传给html,在把错误信息传递过去
else:
objGet=LoginForm()#创建了这个对象
returnrender(request,'login.html',{'obj1':objGet})#然后把对象传给html



html标签,使用login中定义的obj1对应的errors输出

<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<title>Title</title>
<style>
.error-msg{
color:red;
}
</style>
</head>
</head>
<body>
<formaction="/app01/login/"method="POST">
<div>
<div>
{{obj1.user}}
{%ifobj1.errors.user%}
<spanclass="error-msg">{{obj1.errors.user.0}}</span>

{%endif%}
</div>
<div>
{{obj1.pwd}}
<spanclass="error-msg">{{obj1.errors.pwd.0}}</span>
</div>
<div>
{{obj1.num}}
<spanclass="error-msg">{{obj1.errors.num.0}}</span>
</div>
<div>
{{obj1.phone}}
<spanclass="error-msg">{{obj1.errors.phone.0}}</span>
</div>
<div>
{{obj1.test}}
<spanclass="error-msg">{{obj1.errors.test.0}}</span>

</div>
<inputtype="submit"value="提交">
</div>
</form>
</body>
</html>


这样如果,我都按照要求提交,就可以取到数据了?这样咱们就不用自己去拿数据是

{'user':'asfd','num':1,'pwd':'dsafss','test':'32','phone':'13331525685'}


3、form表单定制化

3.1、自定义报错内容

在form里有一个参数:error_messages在他这里就可以定义报错内容

classUserInfo(forms.Form):
email=forms.EmailField(required=True,error_messages={'required':u'邮箱不能为空'})#required是否可以为空,如果为False说明可以为空
host=forms.CharField(error_messages={'required':u'主机不能为空'})#如果required不写默认为Ture
port=forms.CharField(error_messages={'required':u'端口不能为空'})
mobile=forms.CharField(error_messages={'required':u'手机不能为空'},
widget=forms.TextInput(attrs={'class':'form-control','placeholder':u'手机号码'})#给input添加属性
#这里默认是TextInput,标签
)


效果:



3.2给userinfo增加一个备注

classUserInfo(forms.Form):
email=forms.EmailField(required=True,error_messages={'required':u'邮箱不能为空'})#required是否可以为空,如果为False说明可以为空
host=forms.CharField(error_messages={'required':u'主机不能为空'})#如果required不写默认为Ture
port=forms.CharField(error_messages={'required':u'端口不能为空'})

#默认mobile里有一个默认为空的机制,我们在原有的参数里增加怎们自定义的方法
mobile=forms.CharField(validators=[mobile_validate,],#应用咱们自己定义的规则
error_messages={'required':u'手机不能为空'},
widget=forms.TextInput(attrs={'class':'form-control','placeholder':u'手机号码'})
#这里默认是TextInput,标签
)
#咱们在新增一个备注
memo=forms.CharField(required=False,
widget=forms.Textarea(attrs={'class':'form-control','placeholder':u'备注'})

)


效果如下:



3.3生成select标签

classUserInfo(forms.Form):
email=forms.EmailField(required=True,error_messages={'required':u'邮箱不能为空'})#required是否可以为空,如果为False说明可以为空
host=forms.CharField(error_messages={'required':u'主机不能为空'})#如果required不写默认为Ture
port=forms.CharField(error_messages={'required':u'端口不能为空'})

#默认mobile里有一个默认为空的机制,我们在原有的参数里增加怎们自定义的方法
mobile=forms.CharField(validators=[mobile_validate,],#应用咱们自己定义的规则
error_messages={'required':u'手机不能为空'},
widget=forms.TextInput(attrs={'class':'form-control','placeholder':u'手机号码'})
#这里默认是TextInput,标签
)
#咱们在新增一个备注
memo=forms.CharField(required=False,
widget=forms.Textarea(attrs={'class':'form-control','placeholder':u'备注'})

)

user_type_choice=(
(0,u'普通用户'),
(1,u'高级用户'),)

user_type=forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,attrs={'class':'form-control'}))




3.4、关于后端验证

这个后端验证是必须要有验证机制的,前端可以不写但是后端必须要写!前端的JS是可以被禁用掉到。

3.5Django优化错误信息显示

设置显示error的样式

error_msg=user_input_obj.errors.as_data()#这里原来什么都没写,默认是ul的样式,默认是as_ul(),如果我们写成as_data()返回的就是一个原生的字符串
#还有一个as_json


实例:

importre
fromdjangoimportforms
fromdjango.core.exceptionsimportValidationError

#自定义方法
defmobile_validate(value):
mobile_re=re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')#正则匹配
ifnotmobile_re.match(value):
raiseValidationError('手机号码格式错误')#如果没有匹配到主动出发一个错误

classUserInfo(forms.Form):

user_type_choice=(
(0,u'普通用户'),
(1,u'高级用户'),)

user_type=forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,attrs={'class':'form-control'}))

email=forms.EmailField(required=True,error_messages={'required':u'邮箱不能为空'})#required是否可以为空,如果为False说明可以为空
host=forms.CharField(error_messages={'required':u'主机不能为空'})#如果required不写默认为Ture
port=forms.CharField(error_messages={'required':u'端口不能为空'})

#默认mobile里有一个默认为空的机制,我们在原有的参数里增加怎们自定义的方法
mobile=forms.CharField(validators=[mobile_validate,],#应用咱们自己定义的规则
error_messages={'required':u'手机不能为空'},
widget=forms.TextInput(attrs={'class':'form-control','placeholder':u'手机号码'})
#这里默认是TextInput,标签
)
#咱们在新增一个备注
memo=forms.CharField(required=False,
widget=forms.Textarea(attrs={'class':'form-control','placeholder':u'备注'}))

defuser_list(request):
obj=UserInfo()#创建了这个对象
ifrequest.method=='POST':
#获取用户输入一句话就搞定
user_input_obj=UserInfo(request.POST)

ifuser_input_obj.is_valid():#判断用户输入是否合法
data=user_input_obj.clean()#获取用户输入
print(data)
else:
#如果发生错误,捕捉错误
error_msg=user_input_obj.errors.as_data()#这里原来什么都没写,默认是ul的样式,默认是as_ul(),如果我们写成as_data()返回的就是一个原生的字符串
#还有一个as_json

print(error_msg)#打印一下然后看下他的类型
#然后把错误信息返回
returnrender(request,'user_list.html',{'obj':obj,'errors':error_msg,})#然后把对象传给html,在把错误信息传递过去
returnrender(request,'user_list.html',{'obj':obj,})#然后把对象传给html



html

{%loadmytag%}

<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<title>Shuai</title>
</head>
<body>
<formaction="/app01/user_list/"method="post">
<p>用户类型:{{obj.user_type}}<span>{%error_messageerrors.user_type%}</span></p>
<p>主机:{{obj.host}}<span>{%errors.host%}</span></p>
<p>端口:{{obj.port}}<span>{%error_messageerrors.port%}</span></p>
<p>邮箱:{{obj.email}}<span>{%error_messageerrors.email%}</span></p>
<p>手机:{{obj.mobile}}<span>{%error_messageerrors.mobile%}</span></p>
<p>备注:{{obj.memo}}<span>{%error_messageerrors.memo%}</span></p>
<inputtype="submit"value="submit"/>
</form>
</body>
</html>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: