$Django Form组件

forms组件
 -forms是什么?
  就是一个类,可以校验字段(前台传过来的字段)
 -怎么用:
 ***    {#浏览器的格式校验提示   novalidate取消提示: 可以提交 格式不符合浏览器格式 的数据    #}
            <form method="post" novalidate></form>
 ***总结
  
from django import forms
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
from django.forms import widgets
from django.http import JsonResponse
class MyForm(forms.Form):
name=forms.CharField(max_length=8,min_length=3,widget=widgets.TextInput(attrs={'placeholder':'输入用户名','class':'form-control name'}),label='用户名:',error_messages={'max_length':'不能过8位'})
pwd=forms.CharField(max_length=8,min_length=3,widget=widgets.PasswordInput(attrs={'placeholder':'输入密码','class':'form-control pwd'}),label='密码',error_messages={'min_length':'不能少于3位'})
pwd2=forms.CharField(max_length=8,min_length=3,widget=widgets.PasswordInput(attrs={'placeholder':'重复密码','class':'form-control pwd2'}),label='重复密码',error_messages={'min_length':'不能少于3位'})
email=forms.EmailField(widget=widgets.EmailInput(attrs={'placeholder':'输入邮箱','class':'email form-control'}),label='邮箱',error_messages={})
tim=forms.DateTimeField(widget=widgets.TimeInput(attrs={'class':'form-control tim','placeholder':'输入时间'}),label='时间')
def clean_name(self):
name=self.cleaned_data.get('name')
if name=='123':
raise ValidationError('名字错误1')
return name
def clean(self):
pwd=self.cleaned_data.get('pwd')
pwd2=self.cleaned_data.get('pwd2')
if pwd==pwd2:
return self.cleaned_data
else:
raise ValidationError('密码不一致')
def ss(request):
if request.method=='GET':
dic={'name':'123','pwd':'45w','pwd2':'45aa','email':"123@qq.com",'tim':'2018-10-19 00:00:00','age':18}
f=MyForm(dic)
# print(f.cleaned_data) #报错 因为是校验后的数据
if f.is_valid(): #MyForm内【所有的字段】 第一次校验格式通过了 【再进行】 第二次逻辑校验了通过 走下面
print('校验成功字段1',f.cleaned_data)
else:#有一个字段,有一次校验没通过 走这里
print('校验成功段',f.cleaned_data)
print('所有失败的字段',f.errors.as_data())
#取出逻辑错误字段(错误种可能只有格式错误,所以要try)
#【第一次格式都没通过】,【不会进行/不存】在逻辑的【校验/错误】 2次密码格式都没通过只会报格式错误
try:
all=f.errors.as_data().get('__all__')[0]
print(type(all))
except Exception:
all=''
return render(request,'ss.html')

  【视图函数部分】
 -校验字段功能:
  -先写一个类,继承Form

  from django.shortcuts import render, HttpResponse

  from django import forms
  from django.core.exceptions import NON_FIELD_ERRORS, ValidationError   
 
  # 写一个类,要校验那些字段,就是类的属性
  class MyForm(forms.Form):
   # 定义一个属性,可以用来校验字符串类型
   # 限制最大长度是8,最小长度是3
 
name=forms.CharField(max_length=8,min_length=3,label='用户名:',widget=widgets.TextInput(attrs={'class':'form-control name1',' placeholder':'大于3位小于8位'}),error_messages={'max_length':'不能超过8位数','min_length':'不能少于3位数','required':'*必填'})

   pwd=forms.CharField(max_length=8,min_length=3,required=True)
 
   # 校验是否是邮箱格式
   email=forms.EmailField() # errors_messages有个
'invalid':'邮箱地址格式错误'
  def login(request):
   #实例化产生对象,传入要校验的数据(字典)
   myform=MyForm(request.POST)
   # is_valid如果是true表示校验成功,反之,校验失败
   #校验失败的信息(  总的一个失败的信息  )
    print(myform.errors)     #标签形式的错误信息
  print(myform.errors.as_data()) #字典形式的错误信息
   if myform.is_valid(): (第一层校验的字段 通过)
    # 校验通过的数据
    print(myform.cleaned_data)
    return HttpResponse('校验成功')
   else:
    print(myform.cleaned_data)
   return render(request,'login.html',local())
 【template层】   
  -注意:校验字段可以多,但是不能少
     传过来的字典必须有form类的校验字段 少了
 -渲染模板
  -第一中方式:(灵活性最高)
   <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><span>{{  foo.errors.0  }}</span> #渲染错误信息
    {% endfor %}
    <input type="submit" value="提交">
   </form>
  -第三种方式(不建议用):
   <form action="" method="post" >
  {#    {{ myform.as_p }}#}
   {{ myform.as_ul }}
   <input type="submit" value="提交">
   </form>
   
 -渲染错误信息(第一层校验(报错的字段   不会进行第二次校验))
                              错误信息都在 myform({字典}).errors.as_data() 字典内包含了1,2层 (有1的一层 没2层)
  - 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>
  
 -局部钩子校验(第二层校验
  -定义一个函数,名字叫:clean_字段名字,内部,取出该字段,进行校验,如果通过,将该字段返回,如果失败,抛异常(ValidationError)
  -   def clean_name(self):
    # self:当前form对象
    name = self.cleaned_data.get('name')
    if name.startswith('sb'):
     # 失败,抛异常
     raise ValidationError('不能以傻逼开头')
    # 正常,把name返回
    return name
 -全局钩子 (第二层校验
  #重写clean方法
  def clean(self):
   #程序能走到该函数,前面校验已经通过了,所以可以从cleaned_data中取出密码和确认密码  
   pwd=self.cleaned_data.get('pwd')
   re_pwd=self.cleaned_data.get('re_pwd')
   #进行自己的校验
   if pwd==re_pwd:
    #通过,直接返回cleaned_data
    return self.cleaned_data
   else:
    #失败,抛异常(ValidationError)
    raise ValidationError('两次密码不一致')
 
 
 
 
 
 
 
from django import forms
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
class Myform(forms.Form):
from django.forms import widgets
name=forms.CharField(max_length=8,min_length=3,label='用户名:',widget=widgets.TextInput(attrs={'class':'form-control name1',' placeholder':'大于3位小于8位'}),error_messages={'max_length':'不能超过8位数','min_length':'不能少于3位数','required':'*必填'})
pwd=forms.CharField(max_length=8,min_length=3,label='密码:',widget=widgets.PasswordInput(attrs={'class':'form-control pwd1','placeholder':'大于3位小于8位'}),error_messages={'max_length':'不能超过8位数','min_length':'不能少于3位数','required':'*必填',})
r_pwd=forms.CharField(max_length=8,min_length=3,label='确认密码:',widget=widgets.PasswordInput(attrs={'class':'form-control pwd2','placeholder':'大于3位小于8位'}),error_messages={'max_length':'不能超过8位数','min_length':'不能少于3位数','required':'*必填'})
email=forms.EmailField(widget=widgets.EmailInput(attrs={'class':'form-control email1','placeholder':'例如:www@qq.com'}),error_messages={'required':'不能为空','invalid':'邮箱地址格式错误'})
#'invalid':'格式错误'邮箱的格式
# 钩子:在上面error-messages格式校验之后 再次进行的数据校验(上面name数据格式没通过(前台显示错误),不会进行name数据校验.两个错误是独立的)
# 局部钩子
def clean_name(self):
name=self.cleaned_data.get('name')
names=models.Info.objects.only('name')
names=[i.name for i in names]
if name in names:
raise ValidationError('姓名已存在')
return name
# 全局钩子
def clean(self):
pwd=self.cleaned_data.get('pwd')
r_pwd=self.cleaned_data.get('r_pwd')
if pwd!=r_pwd:
raise ValidationError('密码不一致')
return self.cleaned_data
def form(request):
if request.method=='GET':
myform=Myform()
elif request.method=='POST':
myform=Myform(request.POST)
print (myform.errors.as_data ()) #所有的 错误信息(字段格式错误信息 局部钩子 全局钩子信息)
if myform.is_valid(): #通过格式校验
print('true',myform.cleaned_data) #格式 通过的数据{'name': '王冬123', 'pwd': 'bbbbbb', 'r_pwd': 'cccccc', 'email': '279829702@qq.com'}
return redirect('http://www.baidu.com')
else:
print('else',myform.cleaned_data) #格式 通过的数据

print(myform.errors) #type()为一个继承了dict的类
# ul class="errorlist"><li>name<ul class="errorlist"><li>不能少于3位数</li></ul></li><li>pwd<ul class="errorlist"><li>不能少于3位数</li></ul></li><li>r_pwd<ul class="errorlist"><li>不能少于3位数</li></ul></li><li>email<ul class="errorlist"><li>邮箱地址格式错误</li></ul></li></ul>
print (myform.errors.as_data ())
#{'name': [ValidationError(['不能少于3位数'])], 'pwd': [ValidationError(['不能少于3位数'])], 'r_pwd': [ValidationError(['不能少于3位数'])], 'email': [ValidationError(['邮箱地址格式错误'])]}
try:
all=myform.errors.as_data ().get('__all__')[0]
print(all)
except Exception:
pass

return render(request,'form.html',locals())



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
<script src="/static/bootstrap-3.3.7-dist/jquery-3.3.1.js"></script>
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.js"></script>
</head>
<body>
<h1>注册</h1>
<div class="container-fluid " style="margin-top: 100px">
<div class="row">
<div class="col-xs-4 col-xs-offset-4">
{#浏览器的格式校验提示 novalidate取消提示: 可以提交格式不符合的数据 #}
<form method="post" novalidate>

{% for foo in myform %}
<div class="form-group">
{{ foo.label }}{{ foo }}<span style="color: red">{{ foo.errors.0 }}</span>
</div>
{% endfor %}

<button class="btn btn-default">提交 </button><span style="color: red" >{{ all.0 }}</span>
</form>
</div>
</div>
</div>
</body>
<script>
$('.btn').click(function () {
$.ajax({
url:"/form",
type:'post',
data:{'name':$('.name1').val(),'pwd':$('.pwd1').val(),'r_pwd':$('.pwd2').val(),'email':$('.email1').val()},
success(data){

}
});
})
if ($('span').text()){
$('input').val('');
$('html').click(function () {
$('span').text('');
})
}
</script>
</html>
原文地址:https://www.cnblogs.com/3sss-ss-s/p/9996947.html