1.forms组件简介
forms就是一个类,可以校验字段(前台传过来的字段)
2.forms使用方法
-校验字段功能:
-先写一个类,继承Form
from django.shortcuts import render, HttpResponse
from django import forms
# 写一个类,要校验那些字段,就是类的属性
class MyForm(forms.Form):
# 定义一个属性,可以用来校验字符串类型
# 限制最大长度是8,最小长度是3
name=forms.CharField(max_length=8,min_length=3)
pwd=forms.CharField(max_length=8,min_length=3,required=True)
# 校验是否是邮箱格式
email=forms.EmailField()
-使用:
#实例化产生对象,传入要校验的数据(字典)
myform=MyForm(request.POST)
# is_valid如果是true表示校验成功,反之,校验失败
if myform.is_valid():
# 校验通过的数据
print(myform.cleaned_data)
return HttpResponse('校验成功')
else:
print(myform.cleaned_data)
#校验失败的信息
print(myform.errors)
-注意:校验的字段,可以多,但是不能少
-渲染模板
-第一中方式:(灵活性最高)
<form action="" method="post" >
<p>用户名: {{ myform.name }}</p>
<p>密码: {{ myform.pwd }}</p>
<p>邮箱: {{ myform.email }}</p>
<input type="submit" value="提交">
</form>
-第二种方式:for循环form对象(用的比较多):
<form action="" method="post" >
{% for foo in myform %}
<p>{{ foo.label }}:{{ foo }}</p>
{% endfor %}
<input type="submit" value="提交">
</form>
-第三种方式(不建议用):
<form action="" method="post" >
{# {{ myform.as_p }}#}
{{ myform.as_ul }}
<input type="submit" value="提交">
</form>
-渲染错误信息
- myforms有errors
-属性(name)也有errors
-错误信息,变成中文:
- error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '这个必须填','invalid': '不符合邮箱格式'}
-给input标签指定样式,指定格式:
-widget=widgets.TextInput(attrs={'class':'form-control'})
-模板,渲染错误信息:<span>{{ myform.name.errors.0 }}</span>
前端代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="/static/jquery-3.3.1.js"></script> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> <title>Title</title> </head> <body> <form action="" method="post"> {# 注意,这里的name要和models里class创建的类里的字段对应上#} <p>用户名:<input type="text" name="name"></p> <p>密码:<input type="password" name="password"></p> <p>确认密码:<input type="password" name="pwd"></p> <p>邮箱:<input type="text" name="email"></p> <button>提交</button> </form> </body> </html>
前端渲染代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="/static/jquery-3.3.1.js"></script> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> <title>Title</title> </head> <body> {#<h2>第一种方式</h2>#} {#<form action="" method="post">#} {# 注意,这里的name要和models里class创建的类里的字段对应上#} {# 这样渲染的话,必须要符合条件才能被提交#} {# <p>用户名:{{ myform.name }}</p>#} {# <p>密码:{{ myform.password }}</p>#} {# <p>邮箱:{{ myform.email }}</p>#} {# <button>提交</button>#} {#</form>#} {#建议使用第二种,这种扩展性比较好,比较灵活#} {#<hr>#} <h2>第二种方式</h2> {#写上novalidate后,在前端表单就不会验证错误信息了#} <form action="" method="post" novalidate> {% for foo in myform %} {# label可以在views里的类里进行定义标签#} <p>{{ foo.label }}:{{ foo }}<span style="color: red">{{ foo.errors.0 }}</span></p> {% endfor %} <button>提交</button> </form> {#<hr>#} {#<h2>第三种方式</h2>#} {#<form action="" method="post">#} {# {{ myform.as_p }}#} {# <button>提交</button>#} {#</form>#} </body> </html>
后台代码(包含局部钩子部分)
注意,能走到局部钩子部分,说明这部分的数据已经通过forms校验了,才能进行自定义钩子校验。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
from django.shortcuts import render, HttpResponse, redirect, reverse from django.core.exceptions import ValidationError # Create your views here. # 第一步:先要继承From from django import forms from django.forms import widgets class MyForm(forms.Form): # 定义一个属性,可以用来校验字符串类型 # 可以在字段里自定义错误信息 # max_length,最大长度,min_length最小长度,required输入为空时提示内容,widget设置提交的格式 # widget=widgets.PasswordInput()则表示是password格式,里面还可以接参数,控制样式 # widget=widgets.TextInput(attrs={'class':'form-control'}) name = forms.CharField(max_length=8, min_length=3, label='用户名', error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '请输入内容'}, widget=widgets.TextInput(attrs={'class': 'form-control'})) password = forms.CharField(max_length=8, min_length=3, required=True, label='密码', error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '请输入内容'}, widget=widgets.PasswordInput()) # 这里required=默认设置是True # 校验是否是邮箱格式 email = forms.EmailField(label='邮箱', error_messages={'required': '请输入内容', 'invalid': '请输入正确的邮箱格式'}) # aa = forms.CharField(label='选择', error_messages={'required': '请输入内容'}, widget=widgets.CheckboxInput()) #还有自定义其他筛选条件时,可以def clean函数 def clean_name(self): #self 当前form对象 name=self.cleaned_data.get('name') if name.startswith('sb'): #失败,抛异常 raise ValidationError('不能以煞笔开头') #正常,把name返回 return name # def index(request): # #生成对象时(实例化),需要传入要校验的数据(字典) # dic={'name':'lzq','pwd':'123','email':'123qq.com'} # myform=MyForm(dic) # #cleaned_data是校验通过的数据 # #is_valid如果是true表示校验成功,反之,校验失败 # if myform.is_valid(): # print(myform.cleaned_data)#cleaned_data要放在is_valid()后面 # return HttpResponse('校验成功') # else: # print(myform.cleaned_data) # # print(myform.errors)#错误信息,它是一个字典。 # print(myform.errors.as_data)#这样是真正的错误信息,这是个列表,因为可能有多个错误信息 # return HttpResponse('校验失败') # 数据从前端传过来 # 要校验的字典,可以多参数,但是不能少。 # def index(request): # if request.method=='GET': # return render(request,'index.html') # else: # name=request.POST.get('name') # password=request.POST.get('password') # email=request.POST.get('email') # pwd=request.POST.get('pwd') # dic={'name':name,'password':password,'email':email,'pwd':pwd}#数据多了字段可以,但是少了字段会报错 # myform=MyForm(dic) # if myform.is_valid(): # print(myform.cleaned_data) # return HttpResponse('校验成功') # else: # print(myform.cleaned_data) # print(myform.errors.as_data) # return HttpResponse('校验失败') # 渲染模板的功能 # def index(request): # myform=MyForm() # if request.method=='GET': # return render(request,'index2.html',locals()) # 渲染错误信息 def index(request): myform = MyForm() if request.method == 'GET': return render(request, 'index2.html', locals()) elif request.method == 'POST': myform = MyForm(request.POST) if myform.is_valid(): print(myform.cleaned_data) else: print(myform.cleaned_data) print(myform.errors.as_data) return render(request, 'index2.html', locals())
3.全局钩子
注意,能走到全局钩子部分,说明数据已经通过forms校验了,才能进行全局钩子校验
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
from django.shortcuts import render, HttpResponse, redirect, reverse from django.core.exceptions import ValidationError # Create your views here. # 第一步:先要继承From from django import forms from django.forms import widgets from app01 import models class MyForm(forms.Form): # 定义一个属性,可以用来校验字符串类型 # 可以在字段里自定义错误信息 # max_length,最大长度,min_length最小长度,required输入为空时提示内容,widget设置提交的格式 # widget=widgets.PasswordInput()则表示是password格式,里面还可以接参数,控制样式 # widget=widgets.TextInput(attrs={'class':'form-control'}) name = forms.CharField(max_length=8, min_length=3, label='用户名', error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '请输入内容'}, widget=widgets.TextInput(attrs={'class': 'form-control'})) password = forms.CharField(max_length=8, min_length=3, required=True, label='密码', error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '请输入内容'}, widget=widgets.PasswordInput()) # 这里required=默认设置是True re_password = forms.CharField(max_length=8, min_length=3, required=True, label='确认密码', error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '请输入内容'}, widget=widgets.PasswordInput()) # 校验是否是邮箱格式 email = forms.EmailField(label='邮箱', error_messages={'required': '请输入内容', 'invalid': '请输入正确的邮箱格式'}) # aa = forms.CharField(label='选择', error_messages={'required': '请输入内容'}, widget=widgets.CheckboxInput()) # 还有自定义其他筛选条件时,可以def clean函数 # 能走到下面clean函数的,说明一定是通过了上面的校验 #注意,clean函数,校验完以后,通过clean的一定要返回原来的值,这时源码设定的。 def clean_name(self): # self 当前form对象 name = self.cleaned_data.get('name') if name.startswith('sb'): # 失败,抛异常 raise ValidationError('不能以煞笔开头') # 正常,把name返回,注意,通过校验,则必须返回name的值。这个函数是仿照源码写的 return name def clean(self): password = self.cleaned_data.get('password') re_password = self.cleaned_data.get('re_password') if password == re_password: return self.cleaned_data else: raise ValidationError('两次密码不一致') # def index(request): # #生成对象时(实例化),需要传入要校验的数据(字典) # dic={'name':'lzq','pwd':'123','email':'123qq.com'} # myform=MyForm(dic) # #cleaned_data是校验通过的数据 # #is_valid如果是true表示校验成功,反之,校验失败 # if myform.is_valid(): # print(myform.cleaned_data)#cleaned_data要放在is_valid()后面 # return HttpResponse('校验成功') # else: # print(myform.cleaned_data) # # print(myform.errors)#错误信息,它是一个字典。 # print(myform.errors.as_data)#这样是真正的错误信息,这是个列表,因为可能有多个错误信息 # return HttpResponse('校验失败') # 数据从前端传过来 # 要校验的字典,可以多参数,但是不能少。 # def index(request): # if request.method=='GET': # return render(request,'index.html') # else: # name=request.POST.get('name') # password=request.POST.get('password') # email=request.POST.get('email') # pwd=request.POST.get('pwd') # dic={'name':name,'password':password,'email':email,'pwd':pwd}#数据多了字段可以,但是少了字段会报错 # myform=MyForm(dic) # if myform.is_valid(): # print(myform.cleaned_data) # return HttpResponse('校验成功') # else: # print(myform.cleaned_data) # print(myform.errors.as_data) # return HttpResponse('校验失败') # 渲染模板的功能 # def index(request): # myform=MyForm() # if request.method=='GET': # return render(request,'index2.html',locals()) # 渲染错误信息 def index(request): if request.method == 'GET': myform = MyForm() return render(request, 'index2.html', locals()) elif request.method == 'POST': myform = MyForm(request.POST) if myform.is_valid(): print(myform.cleaned_data) myform.cleaned_data.pop('re_password') models.User.objects.create(**myform.cleaned_data) return redirect('http://www.baidu.com') else: all_error=myform.errors.get('__all__') if all_error: all_error=all_error[0] print(myform.cleaned_data) print(myform.errors.as_data) return render(request, 'index2.html', locals())
全局数据没有通过校验时,这时return返回的页面是渲染留有通过校验部分的数据的页面