Django Form验证

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

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

def register(request):
if request.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()
if count == 0:
if p == p2:
print("注册成功")
models.UserInfo.objects.create(user=u, email=e, password=p)
data_list = models.UserInfo.objects.all()
ret["status"] = True
ret["msg"] = "注册成功,请登录"
return HttpResponse(json.dumps(ret))
# return redirect('/index/')
else:
print('diff')
ret["msg"] = "两次输入密码不一致"
return HttpResponse(json.dumps(ret))
elif len(u) > 0 and count >= 1:
print('用户名已经存在' )
ret["msg"] = "用户名已经存在"
return HttpResponse(json.dumps(ret))
else:
return render( request, 'cmdb/register.html', )
#验证:
#输入不能为空,并且有的可以为空有的不可以为空
#如果email = xxxx 这样合法吗
'''
你在这里是不是需要做一大堆的输入验证啊?并且有很多这种页面会存在这种情况,如果每个函数都这样做估计就累死了
''' if request.method == 'GET':
return render( request, 'cmdb/register.html', )

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

Django的form的作用:

1、生成html标签

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

1、生成html标签

views

from django import forms
class LoginForm(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'})) def login(request):
if request.POST:
objPost = LoginForm(request.POST)
ret = objPost.is_valid()
# print(objPost)
print(ret)
if ret:
print(objPost.clean())
else:
from django.forms.utils import ErrorDict
#print(type(obj.errors),obj.errors.as_json())
# obj1.errors
print(objPost.errors.as_json())
return render(request, 'login.html',{'obj1': objPost})
else:
objGet = LoginForm()
return render(request, 'login.html',{'obj1': objGet})

html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.error-msg{
color: red;
}
</style>
</head>
</head>
<body>
<form action="/app01/login/" method="POST">
<div>
<div>
{{ obj1.user }}
{% if obj1.errors.user %}
<span class="error-msg">{{ obj1.errors.user.0 }}</span> {% endif %}
</div>
<div>
{{ obj1.pwd }}
<span class="error-msg">{{ obj1.errors.pwd.0 }}</span>
</div>
<div>
{{ obj1.num }}
<span class="error-msg">{{ obj1.errors.num.0 }}</span>
</div>
<div>
{{ obj1.phone }}
<span class="error-msg">{{ obj1.errors.phone.0 }}</span>
</div>
<div>
{{ obj1.test }}
<span class="error-msg">{{ obj1.errors.test.0 }}</span> </div>
<input type="submit" value="提交">
</div>
</form>
</body>
</html>

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

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

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

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

捕获错误信息并返回

from django import forms

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

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

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.error-msg{
color: red;
}
</style>
</head>
</head>
<body>
<form action="/app01/login/" method="POST">
<div>
<div>
{{ obj1.user }}
{% if obj1.errors.user %}
<span class="error-msg">{{ obj1.errors.user.0 }}</span> {% endif %}
</div>
<div>
{{ obj1.pwd }}
<span class="error-msg">{{ obj1.errors.pwd.0 }}</span>
</div>
<div>
{{ obj1.num }}
<span class="error-msg">{{ obj1.errors.num.0 }}</span>
</div>
<div>
{{ obj1.phone }}
<span class="error-msg">{{ obj1.errors.phone.0 }}</span>
</div>
<div>
{{ obj1.test }}
<span class="error-msg">{{ obj1.errors.test.0 }}</span> </div>
<input type="submit" value="提交">
</div>
</form>
</body>
</html>

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

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

3、form表单定制化

3.1、自定义报错内容

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

class UserInfo(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增加一个备注

class UserInfo(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标签

class UserInfo(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.5 Django 优化错误信息显示

设置显示error的样式

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

实例:

import re
from django import forms
from django.core.exceptions import ValidationError #自定义方法
def mobile_validate(value):
mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') #正则匹配
if not mobile_re.match(value):
raise ValidationError('手机号码格式错误') #如果没有匹配到主动出发一个错误 class UserInfo(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'备注'}))
def user_list(request):
obj = UserInfo() #创建了这个对象
if request.method == 'POST':
#获取用户输入一句话就搞定
user_input_obj = UserInfo(request.POST) if user_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) #打印一下然后看下他的类型
#然后把错误信息返回
return render(request,'user_list.html',{'obj':obj,'errors':error_msg,})#然后把对象传给html,在把错误信息传递过去
return render(request,'user_list.html',{'obj':obj,})#然后把对象传给html
 

html

{% load mytag %}

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Shuai</title>
</head>
<body>
<form action="/app01/user_list/" method="post">
<p>用户类型:{{ obj.user_type }}<span>{% error_message errors.user_type %}</span></p>
<p>主机:{{ obj.host }}<span>{% errors.host %}</span></p>
<p>端口:{{ obj.port }}<span>{% error_message errors.port %}</span></p>
<p>邮箱:{{ obj.email }}<span>{% error_message errors.email %}</span></p>
<p>手机:{{ obj.mobile }}<span>{% error_message errors.mobile %}</span></p>
<p>备注:{{ obj.memo }}<span>{% error_message errors.memo %}</span></p>
<input type="submit" value="submit"/>
</form>
</body>
</html> 

Django 进阶篇之 Form验证的更多相关文章

  1. 02:Django进阶篇

    目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...

  2. Django进阶篇【1】

    注:本篇是Django进阶篇章,适合人群:有Django基础,关于Django基础篇,将在下一章节中补充! 首先我们一起了解下Django整个请求生命周期: Django 请求流程,生命周期: 路由部 ...

  3. Django进阶篇(一)

    Form django中的Form一般有两种功能: 1.输入html 2.验证用户输入 最简易的form验证: <!DOCTYPE html> <html lang="en ...

  4. Python Django的分页,Form验证,中间件

    本节内容 Django的分页 Form 中间件 1 Django 分页 1.1 Django自带的分页 1.首先来看下我的测试数据环境 ############ models.py ######### ...

  5. Django学习系列之Form验证

    django表单基础 django表单分类 基于django.forms.Form:所有表单类的父类 基于django.forms.ModelForm:可以和模型类绑定的Form Form验证流程 定 ...

  6. django 进阶篇

    models(模型) 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行数据库操作 import MySQLdb def GetLi ...

  7. Python之路【第十七篇】Django进阶篇

    规范 确立规范的好处: 代码可读性高 方便代码的定位极其查找 为以后代码扩容带来便利 场景: 在多个APP的场景下,单个app的URL函数功能较多的时候,我们可以通过以下方法来解决. 把Views写成 ...

  8. django进阶篇

    原文连接:http://www.cnblogs.com/wupeiqi/articles/5246483.html Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创 ...

  9. Python学习-day20 django进阶篇

    Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行 ...

随机推荐

  1. [原创]超强C#图片上传,加水印,自动生成缩略图源代码

    <%@ Page Language=“C#“ AutoEventWireup=“true“ %> <%@ Import Namespace=“System“ %> <%@ ...

  2. GoWeb编程之多路复用

    GoWeb编程多路复用 在web编程中,比如我们要一个Url对应一个处理函数,或者一个页面对应一个静态文件,这些都需要进行处理,这个时候就是我们多路复用派上用场了. package main impo ...

  3. error: xslt-config not found. Please reinstall the libxslt >= 1.1.0 distribution

    解决编译php扩展xsl时出现 error: xslt-config not found. Please reinstall the libxslt >= 1.1.0 distribution ...

  4. 青蛙的约会 扩展欧几里得 方程ax+by=c的整数解 一个跑道长为周长为L米,两只青蛙初始位置为x,y;(x!=y,同时逆时针运动,每一次运动分别为m,n米;问第几次运动后相遇,即在同一位置。

    /** 题目:青蛙的约会 链接:https://vjudge.net/contest/154246#problem/R 题意:一个跑道长为周长为L米,两只青蛙初始位置为x,y:(x!=y,同时逆时针运 ...

  5. windows 下node版管理

    linux 下的node 多版本管理有nvm,windows 下同样有这样的工具gnvm 安装步骤(无node环境): 1.下载并解压缩 gnvm.exe 保存到任意文件夹,并将此文件夹加入到环境变量 ...

  6. Linux gdb调试器

    gdb的启动 --gdb 程序名 [corefile] --corefile是可选的,但能增强gdb的调试能力 --强调:启动gdb必须在编译命里加上"-g"参数,"-g ...

  7. java 获取网页指定内容

    import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; ...

  8. 基于 UML 的业务建模举例

    简介: 对于管理流程咨询项目.大型信息化建设项目和套装管理软件实施项目,对业务环境的分析和理解对项目的成功至关重要.系统.全面理解 IT 系统所处的业务环境,可以帮助 IT 系统能提供正确系统功能,并 ...

  9. 集合映射中的映射列表(使用xml文件)

    如果持久化类具有List对象,我们可以通过映射文件中的类的<list>元素或注释来映射List. 在这里,我们正在使用论坛的场景,其中一个问题有多个答案. 在这里,我们使用论坛的场景,其中 ...

  10. 如何给Eclipse添加一个JDK或JRE

    第一:  第二:  第三:  第四: