zoukankan      html  css  js  c++  java
  • $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>
  • 相关阅读:
    springBoot 2.1.5 pom 文件 unknown 错误
    @HystrixCommand 不能被导包
    SQL数据库连接语句
    ADO.NET中COMMAND对象的ExecuteNonQuery、ExcuteReader和ExecuteScalar方法
    重载和重写的区别
    抽象类和接口的相同点和不同点
    结构详解
    简单工厂和抽象工厂的区别
    DataRead和DataSet的异同
    什么是Web Server
  • 原文地址:https://www.cnblogs.com/3sss-ss-s/p/9996947.html
Copyright © 2011-2022 走看看