django form组件

时间:2019-06-17
本文章向大家介绍django form组件,主要包括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()
    )

  

 

 

原文地址:https://www.cnblogs.com/changwenjun-666/p/11039445.html