zoukankan      html  css  js  c++  java
  • django form组件

    一、django  form 组件

    1、注册功能
    
    1.渲染前端标签获取用户输入      >>>			渲染标签
    2    .获取用户输入传递到后端校验	>>>			校验数据
    3.校验未通过展示错误信息        >>>			展示信息
    
    
    例子:
    def register(request):
        error = {'username': '', 'password': ''}
        if request.method == 'POST':
    	username = request.POST.get('username')
    	password = request.POST.get('password')
    	if 'sb' in username :
    	    error['username'] = '你才是sb'
    	if password == '123':
    	    error['password'] = '密码太简单'
        return render(request, 'register.html', locals())
    				
    	
    html页面:			
    <form action="" method="post" >
    	<p >username: <input type="text" name="username"><span>{{ error.username }}</span></p>
    	<p >password: <input type="password" name="password"><span>{{ error.password }}</span></p>
    	<input type="submit"class="btn btn-success">
    </form>
    
    
    校验数据,校验前端后端都可以做,但是前端可以不做,后端必须得做!!!					
    

      

    2、django form 组件 应该做到的三个功能

    渲染标签
    校验数据
    展示信息

    前提:先定义一个对象,实例化的时候不用传参
                
    from django import forms
    class MyForm(forms.Form):
        name = forms.CharField(max_length=6,label='用户名')
                    password = forms.CharField(max_length=8,min_length=3,label='密码')
                    email = forms.EmailField(label='邮箱')
                            
        def register(request):
        #生成一个空函数
        form_obj = MyForm()
        return render(request,'register.html',locals())
                
                
    form组件只帮你渲染获取用户输入的标签,不会帮你渲染提交按钮,需要手动添加
                
                
    <h1>第一种渲染方式(可扩展性较差)</h1>
    {{ form_obj.as_p }}
    {{ form_obj.as_ul }}
                    
    封装程度太高
                    
                    
    <h1>第二种渲染方式</h1>
    <form action="">
        <p>{{ form_obj.name.label }}{{ form_obj.name }}</p>
                        <p>{{ form_obj.password.label }}{{ form_obj.password }}</p>
                        <p>{{ form_obj.email.label }}{{ form_obj.email }}</p>
        <input type="submit">
    </form>
                    
    <h1>第三种渲染标签的方式</h1>
    <form action="">
        {% for foo in form_obj %}
        <p>{{ foo.label }}{{ foo }}</p>
        {% endfor %}
    </form>
                
    前端取消校验  添加 novalidate 字段即可
    <form action="" method="post" novalidate></form>
            
    渲染标签
    第一步需要一个form类
    from django import forms
    
    class MyForm(forms.Form):
        name = forms.CharField(max_length=6)
        password = forms.CharField(max_length=8,min_length=3)
        email = forms.EmailField(required=True)
    第二步实例化form对象
    form_obj = MyForm({'name':'jason'})
                
    第三步查看数据校验是否合法
    form_obj.is_valid()  # 只有当所有的字段都校验通过才会返回True
                
    第四步查看校验错误的信息
    form_obj.errors  # 这个里面放的是所有校验未通过的字段及错误提示
                    """
                    {
                    'name': ['Ensure this value has at most 6 characters (it has 7).'], 
                    'password': ['Ensure this value has at least 3 characters (it has 2).'], 
                    'email': ['Enter a valid email address.']
                    }
    
                    """
    第五步查看校验通过的数据
    form_obj.cleaned_data  # 符合校验规则数据都会被放到该对象中
    ps:form组件校验数据的规则从上往下依次取值校验
        校验通过的放到cleaned_data
        校验失败的放到errors
    注意:
        form中所有的字段默认都是必须传值的(required=True)
        校验数据的时候可以都传(多传的数据不会做任何的校验>>>不会影响form校验规则)
    校验数据
    form组件提交数据如果数据不合法,页面上会保留之前用户输入的信息
        def register(request):
        #生成一个空函数
        form_obj = MyForm()
        if request.method == 'POST':
            print(request.POST)  #<QueryDict: {'name': ['老李'], 'password': ['123'], 'email': ['119@qq.com']}>
            form_obj = MyForm(request.POST)    #前端将数据传给后端,后端拿到数据,重新生成一个实例化的同名对象
            if form_obj.is_valid():
                return  HttpResponse('ok')
        return render(request,'register.html',locals())
        #此时如果数据格式不正确,html页面会走上两次,就会产生提交数据后,原始的数据继续保留的情况
                    
        在前端页面,后端校验,即通过form_obj对象里含有errors属性,在前端取值,注意errors是一个列表形式的,需要索引取值        
    <form action="" novalidate method="post">
        {% for foo in form_obj %}
         <p>{{ foo.label }} {{ foo }}<span>{{ foo.errors.0}}</span></p>
        {% endfor %}
        <input type="submit">
    </form>
    
                    
    设置前端报错信息的样式:
    from django import forms
    class MyForm(forms.Form):
        username = forms.CharField(max_length=6,label='用户名',error_messages={
                    'max_length':'用户名最长6位',
                    'required':'用户名不能为空',
                })
        password = forms.CharField(max_length=8,min_length=3,label='密码',error_messages={
                    'max_length':'最长为8位',
                    'min_length':'最短为3位',
                    'required':'密码不能为空'
                })
        email = forms.EmailField(label='邮箱',error_messages={
                    'invalid':'邮箱格式不正确',
                    'required':'邮箱不能为空'})
                    
    补充:可以设定输入值为空  required=True   
        <form action="" method="post" novalidate>   前端中取消校验 novalidate
            
            
            
    保存数据
        创建的对象时拿到的正确数据,可以直接**form_obj.cleaned_data传入类中
    from  app1 import models
        def register(request):
            form_obj = MyForm()
        if request.method == 'POST':
            print(request.POST) 
            form_obj = MyForm(request.POST)    
            if form_obj.is_valid():
            #将返回的信息保存
            # print(form_obj.cleaned_data)  是满足校验的字典类型的数据                                    
                      
                     models.User.objects.create(**form_obj.cleaned_data)
        return render(request,'register.html',locals())
            
    补充:需要保证字段名的一致,即models里的字段,与继承forms.Form 类下的字段要保证一致
            
            
            
            
    前端取消校验,并显示错误提示
    <form action="" method="post" novalidate>
        {% for foo in form_obj %}
        <p>
            {{ foo.label }}{{ foo }}
            <span>{{ foo.errors.0 }}</span>
        </p>
            {% endfor %}
            <input type="submit">
    </form       
    展示数据

    3、钩子函数   用来对字段进行校验

    # 局部钩子函数  (单个字段的校验利用局部钩子函数)
    def clean_name(self):
        username = self.cleaned_data.get('username')
        if '666' in username:
    	self.add_error('username','光喊666是不行的,要有真实力!')
            return username  # return还是要加上的,兼容性考虑
        
    
    # 全局钩子函数  (多个字段的校验利用全局钩子函数)
    def clean(self):
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if not password == confirm_password:
    	self.add_error('confirm_password',"两次密码不一致,你这个dsb!")
        return self.cleaned_data
    		
    

      

    4、常用字段及插件

    创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;

    initial

    初始值,input框里面的初始值。

    class LoginForm(forms.Form):
        username = forms.CharField(
            min_length=8,
            label="用户名",
            initial="张三"  # 设置默认值
        )
        pwd = forms.CharField(min_length=6, label="密码")
    

      

    error_messages

    重写错误信息。

    class LoginForm(forms.Form):
        username = forms.CharField(
            min_length=8,
            label="用户名",
            initial="张三",
            error_messages={
                "required": "不能为空",
                "invalid": "格式错误",
                "min_length": "用户名最短8位"
            }
        )
        pwd = forms.CharField(min_length=6, label="密码")
    

      

    password

    加密,也可以添加css样式

    class LoginForm(forms.Form):
        ...
        pwd = forms.CharField(
            min_length=6,
            label="密码",
            widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
        )
    

     

    radioSelect

    单radio值为字符串

    class LoginForm(forms.Form):
        username = forms.CharField(
            min_length=8,
            label="用户名",
            initial="张三",
            error_messages={
                "required": "不能为空",
                "invalid": "格式错误",
                "min_length": "用户名最短8位"
            }
        )
        pwd = forms.CharField(min_length=6, label="密码")
        gender = forms.fields.ChoiceField(
            choices=((1, "男"), (2, "女"), (3, "保密")),
            label="性别",
            initial=3,
            widget=forms.widgets.RadioSelect()
        )
    

      

    单选Select

    class LoginForm(forms.Form):
        ...
        hobby = forms.ChoiceField(
            choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
            label="爱好",
            initial=3,
            widget=forms.widgets.Select()
        )
    

     

    多选Select

    class LoginForm(forms.Form):
        ...
        hobby = forms.MultipleChoiceField(
            choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
            label="爱好",
            initial=[1, 3],
            widget=forms.widgets.SelectMultiple()
        )
    

      

    单选checkbox

    class LoginForm(forms.Form):
        ...
        keep = forms.ChoiceField(
            label="是否记住密码",
            initial="checked",
            widget=forms.widgets.CheckboxInput()
        )
    

      

    多选checkbox

    class LoginForm(forms.Form):
        ...
        hobby = forms.MultipleChoiceField(
            choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
            label="爱好",
            initial=[1, 3],
            widget=forms.widgets.CheckboxSelectMultiple()
        )
    

      

     

     

  • 相关阅读:
    pig中将两列合并为一列:concat
    最小二乘法拟合二元多次曲线
    动态重新加载Class机制之代码测试
    從 Windows Form ComboBox、ListBox 或 CheckedListBox 控制項加入或移除項目
    C#控件一览表
    C#中combobox 和TreeView控件属性、事件、方法收集
    PHP 分页类 潇湘博客
    一个房屋中介业务建模的实例分析
    使用Limit参数优化MySQL查询 潇湘博客
    word中的字号与实际的字体大小一一对应的关系
  • 原文地址:https://www.cnblogs.com/changwenjun-666/p/11039445.html
Copyright © 2011-2022 走看看