• 8.Django-form组件


     

    1.form组件的校验功能

    文件formsdemo

    models

    from django.db import models
    
    # Create your models here.
    class UserInfo(models.Model):
        name=models.CharField(max_length=32)
        pwd=models.CharField(max_length=32)
        email=models.EmailField()
        tel=models.CharField(max_length=32)

    views

    from django.shortcuts import render, HttpResponse
    
    # Create your views here.
    
    from django import forms
    class UserForm(forms.Form):   #创建form组件就是这个类,名字任意叫;定义的规则可以多写(多的忽略那你)不能少写
        name = forms.CharField(min_length=4)
        pwd = forms.CharField(min_length=4)
        r_pwd = forms.CharField(min_length=4)
        email = forms.EmailField()
        tel = forms.CharField   #forms组件的键的名字和这些字段的名字要一致
    
    
    def reg(request):
        if request.method == "POST":
            print(request.POST)
    #<QueryDict: {'csrfmiddlewaretoken': ['gEVJ683XmW6CKzXzfYDNGLXPuURgOjka6yYUuxGVBp9n1tV78D2APZ1iktJmXKq8'], 'name': ['kris'], 'pwd': ['123'], 'r_pwd': ['123'], 'email': ['1234@qq.com'], 'tel': ['18271182769']}>
    
            #form = UserForm({"name":"yu", "email":"123@qq.com", "xxx":"alex" })  #类的实例化,可以给它传参,只会给你校验字段里边有的数值,没有的不会校验,有的校验完后就会返回True;form组件的校验规则是有几个就要写几个,多了无所谓不能少写,而且传来的也要符合字段规则。
            form = UserForm(request.POST)  #只要能传来这样一个字典,字典对应的键和值;键能跟它的字段匹配上,就可以做校验;前端的form表单的name属性值应该与forms组件字段名称一致。
        
            print(form.is_valid())  #返回一个布尔值,只会返回 True or False 
            if form.is_valid(): #都正确
                print(form.cleaned_data)   #这是全部都是对的键值对{"name":"kris", "email":"123@qq.com"...}
            else:
                # print(form.cleaned_data) #这是两个字典.这里放正确的{"email":"123@qq.com"}
                # print(form.errors)       #这里放错误的 {"name":["......."]}(如果name校验错了)
       ##<ul class="errorlist"><li>name<ul class="errorlist"><li>该用户已注册</li></ul></li><li>pwd<ul class="errorlist"><li>Ensure this value has at least 4 characters (it has 3).</li></ul></li><li>r_pwd<ul class="errorlist"><li>Ensure this value has at least 4 characters (it has 3).</li></ul></li></ul> # print(type(form.errors)) #ErrorDict <class 'django.forms.utils.ErrorDict'> print(form.errors.get("name")) #<ul class="errorlist"><li>该用户已注册</li></ul> print(type(form.errors.get("name"))) #ErrorDict <class 'django.forms.utils.ErrorList'> print(form.errors.get("name")[0]) 该用户已注册 ''' if 所有字段校验成功,则
          form.is_valid()
          form.cleaned_data:{"name":"kris", "email":"123@qq.com"} 校验都通过之后,所有字段的信息都在这里边。
          form.errors
    ''' return HttpResponse("OK") return render(request, "reg.html") #这是get请求

    reg.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="" method="post">
            {% csrf_token %}
            <p>用户名<input type="text" name="name"></p>
            <p>密码<input type="password" name="pwd"></p>
            <p>确认密码<input type="password" name="r_pwd"></p>
            <p>邮箱<input type="text" name="email"></p>
            <p>手机号<input type="text" name="tel"></p>
    
            <input type="submit">
        </form>
    </body>
    </html>

    2.渲染标签

    reg.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="" method="post">
            {% csrf_token %}
            <p>用户名<input type="text" name="name"></p>
            <p>密码<input type="password" name="pwd"></p>
            <p>确认密码<input type="password" name="r_pwd"></p>
            <p>邮箱<input type="text" name="email"></p>
            <p>手机号<input type="text" name="tel"></p>
    
            <input type="submit">
        </form>
    
        <hr>  //
        <h3>forms组件的渲染方式1</h3>  //form表单的name值,应该与forms组件的字段的名字一致;django的forms组件怕你写的不一致,这里才有了渲染的功能;是get请求的时候
        <form action="" method="post">
            {% csrf_token %}
            <p>{{ form.name.label }}
                {{ form.name }}
            </p>
            <p>
                {{ form.pwd.label }}
                {{ form.pwd }}
            </p>
            <p>
                确认密码
                {{ form.r_pwd }}
            </p>
            <p>邮箱{{ form.email }}</p>
            <p>手机号{{ form.tel }}</p>
            <input type="submit">
        </form>
    
        <h3>forms组件渲染方式2</h3>  // 渲染出来的是英文,可以在UserForm这个类里边的字段下添加 label标签写上中文
        <form action="" method="post">
            {% csrf_token %}
            {% for field in form %}   //for循环这个form;拿到这个field(每个字段对象,等同与上面方式一的form.name、form.pwd...            <p>
                    <label for="">{{ field.label }}</label>  //每个字段里边加上自己label就可以了,label标签可以跟下面的关联起来。
                    {{ field }}
                </p>
            {% endfor %}
            <input type="submit">
        </form>
    
        <h3>forms组件渲染方式3</h3>
       <form action="" method="post">  {# 不灵活,把样式给固定死了,p标签里边放label标签 #}
            {% csrf_token %}
            {{ form.as_p }}   //调用它下面as_p的方法,它还有as_ul的方法;
            <input type="submit">
        </form>
    </body>
    </html>

    渲染错误信息

    第一个form通过验证已经有一个个的数据了,区别在于它传到reg.html时候,它.name还是input标签,你点提交这个页面没有变;同时它也可以把你传的那个信息给渲染出来作为input标签的value值。

    之所以能看到错误信息,是因为我post提交了构建了一个新form页面,在post请求下加了下面这个:

     return render(request, "reg.html", locals()) 

    reg.html

        <h3>forms组件的渲染方式1</h3>
        <form action="" method="post" novalidate>
            {% csrf_token %}
            <p>{{ form.name.label }}
                {{ form.name }}<span>{{ form.name.errors.0 }}</span> //有错误信息就放,没有就不显示
            </p>
            <p>
                {{ form.pwd.label }}
               {{ form.pwd }}<span>{{ form.pwd.errors.0 }}</span>  {#这里放错误信息,它自己的errors#}
            </p>
            <p>
                确认密码
                {{ form.r_pwd }}<span>{{ form.r_pwd.errors.0 }}</span>
            </p>
            <p>邮箱{{ form.email }}<span>{{ form.email.errors.0 }}</span></p>
            <p>手机号{{ form.tel }}<span>{{ form.tel.errors.0 }}</span></p>
            <input type="submit">
        </form>

    views

    from django.shortcuts import render, HttpResponse
    
    # Create your views here.
    
    from django import forms
    class UserForm(forms.Form):   #创建form组件就是这个类,名字任意叫;定义的规则可以多写(多的忽略那你)不能少写
        name = forms.CharField(min_length=4, label="用户名")
        pwd = forms.CharField(min_length=4, label="密码")
        r_pwd = forms.CharField(min_length=4,label="确认密码")
        email = forms.EmailField(label="邮箱")
        tel = forms.CharField(label="手机号")
    
    
    def reg(request):
        if request.method == "POST":
            print(request.POST)
    
    
            #form = UserForm({"name":"yu", "email":"123@qq.com"})  #类的实例化,可以给它传参
            form = UserForm(request.POST)  #只要能传来这样一个字典,字典对应的键和值;键能跟它的字段匹配上,就可以做校验;前端的form表单的name属性值应该与forms组件字段名称一致。
                #你这个form已经通过验证传一个个数据了;已绑定数据表单对象的form
            print(form.is_valid())  #返回一个布尔值 通过校验之后的form
            if form.is_valid(): #都正确           经过验证之后的form
                print(form.cleaned_data)   #这是全部都是对的{"name":"kris", "email":"123@qq.com"}
            else:
                print(form.cleaned_data) #这是两个字典.这里放正确的{"email":"123@qq.com"}
                # print(form.errors)  #这里放错误的 {"name":["......."]}
                # print(type(form.errors)) #ErrorDict
    
                # print(form.errors.get("name"))
                # print(type(form.errors.get("name"))) #ErrorDict
                # print(form.errors.get("name")[0])
                return render(request, "reg.html", locals())  #如果校验失败后,它返回这个页面,可以把第一次输入的信息给保存了,作为value值;它走的是post请求
            ''' 之所以post提交后可以保存输入的信息,因为这两个form不是一个
            if 所有字段校验成功,则form.cleaned_data:{"name":"kris", "email":"123@qq.com"}
            '''
    
            #return HttpResponse("OK")  get请求是走下面这个
        form=UserForm()  #未绑定数据表单对象,上边的form是绑定表单对象 #这个form跟上边那个form = UserForm(request.POST) 是不一个form;上边的form即使验证失败了它会给你保留你输入的values值
        return render(request, "reg.html", locals()) #把值传进来进行渲染;get请求

    3.forms组件的参数配置

    reg.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6     <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
     7     <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
     8 </head>
     9 <body>
    10 <div class="container">
    11     <div class="row">
    12         <div class="col-md-6 col-lg-offset-3">
    13 {#            <form action="" method="post">#}
    14 {#                {% csrf_token %}#}
    15 {#                <p>用户名<input type="text" name="name"></p>#}
    16 {#                <p>密码<input type="password" name="pwd"></p>#}
    17 {#                <p>确认密码<input type="password" name="r_pwd"></p>#}
    18 {#                <p>邮箱<input type="text" name="email"></p>#}
    19 {#                <p>手机号<input type="text" name="tel"></p>#}
    20 {#        #}
    21 {#                <input type="submit">#}
    22 {#            </form>#}
    23 
    24             <hr>
    25             <h3>forms组件的渲染方式1</h3>
    26             <form action="" method="post" novalidate>
    27                 {% csrf_token %}
    28                 <p>{{ form.name.label }}
    29                     {{ form.name }}<span>{{ form.name.errors.0 }}</span>
    30                 </p>
    31                 <p>
    32                     {{ form.pwd.label }}
    33                    {{ form.pwd }}<span>{{ form.pwd.errors.0 }}</span>  {#这里放错误信息,它自己的errors#}
    34                 </p>
    35                 <p>
    36                     确认密码
    37                     {{ form.r_pwd }}<span>{{ form.r_pwd.errors.0 }}</span>
    38                 </p>
    39                 <p>邮箱{{ form.email }}<span>{{ form.email.errors.0 }}</span></p>
    40                 <p>手机号{{ form.tel }}<span>{{ form.tel.errors.0 }}</span></p>
    41                 <input type="submit">
    42             </form>
    43 
    44 {#            <h3>forms组件渲染方式2</h3>#}
    45 {#            <form action="" method="post">#}
    46 {#                {% csrf_token %}#}
    47 {#                {% for field in form %}#}
    48 {#                    <p>#}
    49 {#                        <label for="">{{ field.label }}</label>#}
    50 {#                        {{ field }}#}
    51 {#                    </p>#}
    52 {#                {% endfor %}#}
    53 {#                <input type="submit">#}
    54 {#            </form>#}
    55 {#            #}
    56 {#            <h3>forms组件渲染方式3</h3>#}
    57 {#            <form action="" method="post">  {# 不灵活,把样式给固定死了#}
    58 {#                {% csrf_token %}#}
    59 {#                {{ form.as_p }}#}
    60 {#                <input type="submit">#}
    61 {#            </form>#}
    62 
    63         </div>
    64     </div>
    65 </div>
    66 </body>
    67 </html>
    View Code

    views

     1 from django.shortcuts import render, HttpResponse
     2 
     3 # Create your views here.
     4 
     5 from django import forms
     6 
     7 from django.forms import widgets
     8 class UserForm(forms.Form):   #创建form组件就是这个类,名字任意叫;定义的规则可以多写(多的忽略那你)不能少写
     9     name = forms.CharField(min_length=4, label="用户名",error_messages={"required":"该字段不能为空"},
    10                            widget=widgets.TextInput(attrs={"class":"form-control"})
    11                             )
    12     pwd = forms.CharField(min_length=4, label="密码",
    13                           widget=widgets.PasswordInput(attrs={"class":"form-control"}))
    14     r_pwd = forms.CharField(min_length=4,label="确认密码",error_messages={"required":"该字段不能为空"},widget=widgets.TextInput(attrs={"class":"form-control"}))
    15     email = forms.EmailField(label="邮箱",error_messages={"required":"该字段不能为空","invalid":"格式错误"},widget=widgets.TextInput(attrs={"class":"form-control"}))
    16     tel = forms.CharField(label="手机号",widget=widgets.TextInput(attrs={"class":"form-control"}))
    17 
    18 
    19 def reg(request):
    20     if request.method == "POST":
    21         print(request.POST)
    22 
    23 
    24         #form = UserForm({"name":"yu", "email":"123@qq.com"})  #类的实例化,可以给它传参
    25         form = UserForm(request.POST)  #只要能传来这样一个字典,字典对应的键和值;键能跟它的字段匹配上,就可以做校验;前端的form表单的name属性值应该与forms组件字段名称一致。
    26             #你这个form已经通过验证传一个个数据了;已绑定数据表单对象
    27         print(form.is_valid())  #返回一个布尔值
    28         if form.is_valid(): #都正确
    29             print(form.cleaned_data)   #这是全部都是对的{"name":"kris", "email":"123@qq.com"}
    30         else:
    31             print(form.cleaned_data) #这是两个字典.这里放正确的{"email":"123@qq.com"}
    32             # print(form.errors)  #这里放错误的 {"name":["......."]}
    33             # print(type(form.errors)) #ErrorDict
    34 
    35             # print(form.errors.get("name"))
    36             # print(type(form.errors.get("name"))) #ErrorDict
    37             # print(form.errors.get("name")[0])
    38             return render(request, "reg.html", locals())  #如果校验失败后,它返回这个页面
    39         '''
    40         if 所有字段校验成功,则form.cleaned_data:{"name":"kris", "email":"123@qq.com"}
    41         '''
    42 
    43         #return HttpResponse("OK")
    44     form=UserForm  #未绑定数据表单对象 #这个form跟上边那个form = UserForm(request.POST) 是不一个form;上边的form即使验证失败了它会给你保留你输入的values值
    45     return render(request, "reg.html", locals())
    View Code
    from django.forms import widgets
    class UserForm(forms.Form):   #创建form组件就是这个类,名字任意叫;定义的规则可以多写(多的忽略那你)不能少写
        name = forms.CharField(min_length=4, label="用户名",error_messages={"required":"该字段不能为空"}, //错误信息,required是为空错误
                               widget=widgets.TextInput(attrs={"class":"form-control"})  #渲染什么标签通过这里告诉我,这个标签有什么属性通过attrs告诉我,form-control样式就变好看了
                                ) //它默认的就是TextInput类型
        pwd = forms.CharField(min_length=4, label="密码",
                              widget=widgets.PasswordInput(attrs={"class":"form-control"})) //变成密文了
        r_pwd = forms.CharField(min_length=4,label="确认密码",error_messages={"required":"该字段不能为空"},widget=widgets.TextInput(attrs={"class":"form-control"}))
        email = forms.EmailField(label="邮箱",error_messages={"required":"该字段不能为空","invalid":"格式错误"},widget=widgets.TextInput(attrs={"class":"form-control"}))
        tel = forms.CharField(label="手机号",widget=widgets.TextInput(attrs={"class":"form-control"}))

    4.forms组件校验的局部钩子

    views

    from django import forms
    
    from django.forms import widgets
    from app01.models import UserInfo
    from django.core.exceptions import NON_FIELD_ERRORS,ValidationError
    class UserForm(forms.Form):   #创建form组件就是这个类,名字任意叫;定义的规则可以多写(多的忽略那你)不能少写
        name = forms.CharField(min_length=4, label="用户名",error_messages={"required":"该字段不能为空"},
                               widget=widgets.TextInput(attrs={"class":"form-control"})
                                )
        pwd = forms.CharField(min_length=4, label="密码",
                              widget=widgets.PasswordInput(attrs={"class":"form-control"}))
        r_pwd = forms.CharField(min_length=4,label="确认密码",error_messages={"required":"该字段不能为空"},widget=widgets.TextInput(attrs={"class":"form-control"}))
        email = forms.EmailField(label="邮箱",error_messages={"required":"该字段不能为空","invalid":"格式错误"},widget=widgets.TextInput(attrs={"class":"form-control"}))
        tel = forms.CharField(label="手机号",widget=widgets.TextInput(attrs={"class":"form-control"}))
        def clean_name(self): #加一个实例方法 (局部钩子)
            val = self.cleaned_data.get("name")     #拿到上边字段第一次校验的
            ret = UserInfo.objects.filter(name=val) #第二次校验(局部校验)
            if not ret:
                return val
            else:
                raise ValidationError("该用户已注册")  #抛出异常信息错误
        def clean_tel(self):   #限定手机号11位 
            val = self.cleaned_data.get("tel")
            if len(val)==11:
                return val
            else:
                raise ValidationError("手机号格式错误")

     

     5.全局钩子

     forms可单独放在一个py文件里边

    myforms.py

    #Author:Kris
    
    from django import forms
    
    from django.forms import widgets
    from app01.models import UserInfo
    from django.core.exceptions import NON_FIELD_ERRORS,ValidationError
    class UserForm(forms.Form):   #创建form组件就是这个类,名字任意叫;定义的规则可以多写(多的忽略那你)不能少写
        name = forms.CharField(min_length=4, label="用户名",error_messages={"required":"该字段不能为空"},
                               widget=widgets.TextInput(attrs={"class":"form-control"})
                                )
        pwd = forms.CharField(min_length=4, label="密码",
                              widget=widgets.PasswordInput(attrs={"class":"form-control"}))
        r_pwd = forms.CharField(min_length=4,label="确认密码",error_messages={"required":"该字段不能为空"},widget=widgets.TextInput(attrs={"class":"form-control"}))
        email = forms.EmailField(label="邮箱",error_messages={"required":"该字段不能为空","invalid":"格式错误"},widget=widgets.TextInput(attrs={"class":"form-control"}))
        tel = forms.CharField(label="手机号",widget=widgets.TextInput(attrs={"class":"form-control"}))
        def clean_name(self):  ##加一个实例方法
            val = self.cleaned_data.get("name")  #说明它通过上边name字段那层的校验了
            ret = UserInfo.objects.filter(name=val) 
            if not ret:
                return val  #再校验,合格了返回的还是之前的那个val
            else:
                raise ValidationError("该用户已注册")
        def clean_tel(self):
            val = self.cleaned_data.get("tel")  #
            if len(val)==11:
                return val
            else:
                raise ValidationError("手机号格式错误")
    
        def clean(self):                 #两次密码不一致的信息,是全局错误,没有写在任何字段下面
            pwd = self.cleaned_data.get('pwd')
            r_pwd = self.cleaned_data.get('r_pwd')
            if pwd and r_pwd:
                if pwd == r_pwd:
                    return self.cleaned_data
                else: 
                    raise ValidationError('两次密码不一致')
            else:  #如果pwd和r_pwd有一个为空,说明没检验通过
                return self.cleaned_data

    views

    from django.shortcuts import render, HttpResponse
    
    # Create your views here.
    
    from app01.myforms import *
    def reg(request):
        if request.method == "POST":
            print(request.POST)
            #form = UserForm({"name":"yu", "email":"123@qq.com"})  #类的实例化,可以给它传参
            form = UserForm(request.POST)  #只要能传来这样一个字典,字典对应的键和值;键能跟它的字段匹配上,就可以做校验;前端的form表单的name属性值应该与forms组件字段名称一致。
                #你这个form已经通过验证传一个个数据了;已绑定数据表单对象
            print(form.is_valid())  #返回一个布尔值
            if form.is_valid(): #都正确;is_valid帮我们做校验的方法
                print(form.cleaned_data)   #这是全部都是对的{"name":"kris", "email":"123@qq.com"}
            else:
                print(form.cleaned_data) #这是两个字典.这里放正确的{"email":"123@qq.com"}
    
                #全局钩子错误
                #print('errors', form.errors.get('__all__')[0])  #可以写某个字段 --->> 打印: error 两次密码不一致
                errors = form.errors.get('__all__') #有name、email字段错了就写name、email,全局错误就写__all__ ;拿到errors交给模板
    
                return render(request, "reg.html", locals())  #如果校验失败后,它返回这个页面
            '''
            if 所有字段校验成功,则form.cleaned_data:{"name":"kris", "email":"123@qq.com"}
            '''
    
            #return HttpResponse("OK")
        form=UserForm()  #未绑定数据表单对象 #这个form跟上边那个form = UserForm(request.POST) 是不一个form;上边的form即使验证失败了它会给你保留你输入的values值
        return render(request, "reg.html", locals())

    reg.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-lg-offset-3">
    
                <hr>
                <h3>forms组件的渲染方式1</h3>
                <form action="" method="post" novalidate>
                    {% csrf_token %}
                    <p>{{ form.name.label }}
                        {{ form.name }}<span class="pull-right error">{{ form.name.errors.0 }}</span>
                    </p>
                    <p>
                        {{ form.pwd.label }}
                       {{ form.pwd }}<span class="pull-right error">{{ form.pwd.errors.0 }}</span>  {#这里放错误信息,它自己的errors#}
                    </p>
                    <p>
                        确认密码
                        {{ form.r_pwd }}<span class="pull-right error">{{ form.r_pwd.errors.0 }}</span><span class="pull-right error">{{ errors.0 }}</span> //全局错误信息传到模板里边 
                    </p>
                    <p>邮箱{{ form.email }}<span class="pull-right error">{{ form.email.errors.0 }}</span></p>
                    <p>手机号{{ form.tel }}<span class="pull-right error">{{ form.tel.errors.0 }}</span></p>
                    <input type="submit">
                </form>
    
            </div>
        </div>
    </div>
    </body>
    </html>
  • 相关阅读:
    罗美琪和春波特的故事...
    欢迎参与 KubeVela 官方文档翻译活动
    开源 1 年半 star 破 1.2 万的 Dapr 是如何在阿里落地的?
    Service Mesh 从“趋势”走向“无聊”
    Nacos 2.0 性能提升十倍,贡献者 80% 以上来自阿里之外
    阿里巴巴云原生 etcd 服务集群管控优化实践
    KubeVela 1.0 :开启可编程式应用平台的未来
    知行动手实验室可以用来做什么?
    7. Jackson用树模型处理JSON是必备技能,不信你看
    Linux:sudo,没有找到有效的 sudoers 资源
  • 原文地址:https://www.cnblogs.com/shengyang17/p/9126170.html
Copyright © 2020-2023  润新知