Django之forms组件

forms组件

例如我们写一个注册功能,要求是:

​ 用户输入的用户名中 不能包含666
​ 如果包含了 就提示用户 输入的内容不符合社会主义核心价值观
​ 用户输入的密码 不能小于三位
​ 如果密码少于三位 提示用户 密码太短了

这就需要搭建前端页面,对前端用户提交的数据进行校验,将错误信息展示到前端页面给用户看

要注意的是:校验数据通常是前后端都有校验
但是前端校验可有可无 哪怕再牛逼
后端也必须要有校验 反正一句话 前端可有不校验 后端必须校验!!!

1.搭建前端页面 >>> 渲染页面
2.获取前端用户提交的数据校验 >>> 校验数据
3.对数据的校验的结果 展示到前端页面给用户查看 >>> 展示错误信息

forms组件能够自动帮你完成三件事:

  1. 渲染页面
  2. 校验数据
  3. 展示信息

forms组件基本用法

1、首先要先写一个类

from django import forms

class MyRegForm(forms.Form):
	username = forms.CharField(min_length=3,max_length=8)
	password = forms.CharField(min_length=3,max_length=8)
	email = forms.EmailField()

2、如何校验数据

在pycharm下面的Python Console窗口中进行校验测试,会自动搭建测试环境

测试代码:

from app01 import views
# 1.给自定义的类传一个字典
obj = views.MyRegForm({'username':'jason','password':'12','email':'123'})

# 2.判断数据是否全部合法
obj.is_valid()  # 只有数据全部符合要求才会是True
Out[4]: False
    
# 3.查看符合校验规则的数据
obj.cleaned_data
Out[5]: {'username': 'jason'}
    
# 4.查看不符合条件的数据以及不符合的原因是什么
obj.errors
Out[6]: 
{
	'password': ['Ensure this value has at least 3 characters (it has 2).'],
	'email': ['Enter a valid email address.']
}
            
# 5.校验数据的时候 默认情况下类里面所有的字段都必须传值
obj = views.MyRegForm({'username':'jason','password':'123'})
obj.is_valid()
Out[12]: False
obj.errors
Out[13]: {'email': ['This field is required.']}  # 没有给表中的email字段传值,就无法通过校验
    
# 6.默认情况下可以多传 但是绝对不能少传
obj = views.MyRegForm({'username':'jason','password':'1233','email':'123@qq.com','xxx':'ooo'})
obj.is_valid()
Out[15]: True

渲染页面

注意事项:

​ 1.forms组件在帮你渲染页面的时候 只会渲染获取用户输入(输入,选择,下拉框...)的标签 提交按钮需要你手动添加
​ 2.input框的label注释 不指定的情况下 默认用的类中字段的首字母大写

三种渲染前端页面的方式

后端

from django import forms

class MyRegForm(forms.Form):
	username = forms.CharField(min_length=3,max_length=8,label='用户名')
	password = forms.CharField(min_length=3,max_length=8,label='密码')
	email = forms.EmailField(label='邮箱')
    
def formmm(request):
    # 1.生成一个空的对象
    form_obj = MyRegForm()
    if request.method == 'POST':
        # 2.获取用户提交的数据
        # print(request.POST)  # request.POST  其实也可以看成是一个字典
        # 3.借助于form组件帮助我们校验
        form_obj = MyRegForm(request.POST)  # 由于request.POST其实就是一个大字典 所以直接当做参数传入即可  # 注意:这个form_obj对象名必须跟上面的form_obj对象名一致
        # 4.判断用户输入的数据是否符合校验规则
        if form_obj.is_valid():
            return HttpResponse('你上传的数据没有问题')
    return render(request,'formmm.html',locals())

第一种渲染页面的方式(封装程度太高,标签样式及参数不方便调整,可扩展性差,一般只用于本地测试 不推荐使用)

<p>
{{ form_obj.as_p }}  
{{ form_obj.as_ul }}
{{ form_obj.as_table }}    
</p>

第二种渲染页面的方式:扩展性较高,但不足之处在于需要手写的代码量比较多(不推荐使用)

<p>{{ form_obj.username.label }}{{ form_obj.username }}</p>
<p>{{ form_obj.password.label }}{{ form_obj.password }}</p>
<p>{{ form_obj.email.label }}{{ form_obj.email }}</p>
			

第三种渲染前端页面的方式:代码量比较少,可扩展性都很高(推荐使用)

<p>
{% for foo in form_obj %}
    <P>{{ foo.label }}{{ foo }}</P>
{% endfor %}
</p>

想要input框前的名字是中文,在后端的字段中直接加参数label='用户名'

eg :

# views.py
from django import forms
class MyRegForm(forms.Form):
	username = forms.CharField(min_length=3,max_length=8,label='用户名')
	password = forms.CharField(min_length=3,max_length=8,label='密码')
	email = forms.EmailField(label='邮箱')

如何展示错误信息

取消前端校验功能

校验数据的时候可以前后端都校验 做一个双重的校验,但是前端的校验可有可无,而后端的校验则必须要有,因为前端的校验可以通过爬虫直接避开。
前端取消浏览器校验功能:form标签添加novalidate属性即可:<form action="" method='post' novalidate></form>

展示错误信息

展示错误信息:用后端传过来的对象.errors.0

form action="" method="post" novalidate>
    {% for foo in form_obj %}
    <p>
        {{ foo.label }}:{{ foo }}   <!--渲染前端页面-->
        <span style="color: red">{{ foo.errors.0 }}</span>   <!--展示错误信息显示在input框的后面-->
    </p>
    {% endfor %}
    <input type="submit">
</form>

上述的方法展示出来的错误信息时英文,那怎么把它变成中文显示呢,来看以下代码:

from django import forms

class MyRegForm(forms.Form):
	username = forms.CharField(min_length=3,max_length=8,label='用户名',
                              # 指定error_messages参数来把错误信息用中文展示出来
							error_messages={    
								'min_length':'用户名最短三位',  
								'max_length':'用户名最长八位',
								'required':'用户名不能为空'
							},initial='我是初始值'  # 这个参数是给input框设置初始值
							)

	password = forms.CharField(min_length=3,max_length=8,label='密码',
							error_messages={
								'min_length':'密码最短三位',
								'max_length':'密码最长八位',
								'required':'密码不能为空'
							})

	email = forms.EmailField(label='邮箱',error_messages={
								'required':'邮箱不能为空',
								'invalid':'邮箱格式不正确'
							},required=False)   # 把required参数指定为False,表示这个字段的参数可以不传,如果传了的话也依然还是会校验的。

forms组件钩子函数

当你需要对某一个字段数据进行额外的一系列校验,可以考虑使用钩子函数

钩子函数是forms组件暴露给用户,可以自定义的校验规则

必须通过字段本身之前的校验规则,才会进行钩子函数的校验。

用法:在自定义的form类中书写方法即可

局部钩子

针对单个字段的,使用局部钩子

# 局部钩子(针对某一个字段做额外的校验)   校验用户名中不能包含666 一旦包含 提示
def clean_username(self):
	username = self.cleaned_data.get('username')
	if '666' in username:
		# 给username字段下面提示错误信息
		self.add_error('username','光喊666是不行的 你得自己上')
	return username

全局钩子

针对多个字段的校验,使用全局钩子,eg:校验两次密码是否一致

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','两次密码不一致')
	return self.cleaned_data
			

forms组件其他字段及操作方式

required 是否必填
label 注释信息
error_messages 报错信息
initial 默认初始值
widget 控制标签属性和样式

如何改变input框的type属性值

需要给字段指定widget参数来控制标签属性

widget= widgets.TextInput()
widget=widgets.PasswordInput()

如何让forms组件渲染出来的input框有form-control类属性
widget= widgets.TextInput(attrs={'class':'form-control others'}) # 如果有多个类属性 空格隔开
widget=widgets.PasswordInput(attrs={'class':'form-control others'})

eg:

from django import forms
from django.forms import widgets  # 当你forms点不出来的时候 你可以手动导入一下

class MyRegForm(forms.Form):
    username = forms.CharField(min_length=3,max_length=8,label='用户名',
                               error_messages={
                                   'min_length':'用户名最短三位',
                                   'max_length':'用户名最长八位',
                                   'required':'用户名不能为空'
                               },initial='我是初始值',required=False,
                               widget= widgets.TextInput(attrs={'class':'form-control others'})
                               )
    password = forms.CharField(min_length=3,max_length=8,label='密码',error_messages={
                                   'min_length':'密码最短三位',
                                   'max_length':'密码最长八位',
                                   'required':'密码不能为空'
                               },widget=widgets.PasswordInput())
	email = forms.EmailField(label='邮箱',error_messages={
            'required':'邮箱不能为空',
            'invalid':'邮箱格式不正确'
    		},required=False,widget=widgets.EmailInput(attrs={'class':'form-control'}))

其他字段了解知识点(知道有这些对象 需要用到的时候 能够知道去哪找)

# 单选的radio框
gender = forms.ChoiceField(
	choices=((1, "男"), (2, "女"), (3, "保密")),
	label="性别",
	initial=3,
	widget=forms.widgets.RadioSelect()
)

# 单选select框
hobby = forms.ChoiceField(
	choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
	label="爱好",
	initial=3,
	widget=forms.widgets.Select()
)

# 多选的select框
hobby1 = forms.MultipleChoiceField(
	choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
	label="爱好",
	initial=[1, 3],
	widget=forms.widgets.SelectMultiple()
)

# 单选的checkbox框
keep = forms.ChoiceField(
	label="是否记住密码",
	initial="checked",
	widget=forms.widgets.CheckboxInput()
)

# 多选的checkbox框
hobby2 = forms.MultipleChoiceField(
	choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
	label="爱好",
	initial=[1, 3],
	widget=forms.widgets.CheckboxSelectMultiple()
)

每个字段,还支持正则校验

需要导入RegexValidator模块

eg:

from django import forms
from django.forms import Form
from django.core.validators import RegexValidator
         
class MyForm(Form):
	phone = forms.CharField(label='手机号',
		validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
         )
原文地址:https://www.cnblogs.com/zhuangyl23/p/11761129.html