django2.2-form表单详解
文章目录
- 一、form组件
- 二、form表单的基本语法
- 1. form表单类的书写
- 2. 校验数据
- 3. 渲染表单标签
- 三、展示错误信息
- 1. 展示错误信息
- 2. 自定义错误信息
- 3. 动态添加错误信息
- 四、form表单的钩子函数(HOOK)
- 1. 局部钩子(只涉及到一个字段)
- 2. 全局钩子(涉及到多个字段)
- 五、字段参数和类型
- 1. 核心参数
- `widget`参数
- `validators`参数
- 其他参数
- 2. 常用类型
一、form组件
通常情况下,我们需要自己手动在HTML页面中,编写form标签和其内的其它元素。但这费时费力,而且容易出错,数据验证也比较麻烦。
因此,Django在内部集成了一个表单模块,专门用来帮助我们快速处理表单相关的内容。Django的表单模块给我们提供了下面三个主要功能:
- 准备和重组数据,用于页面渲染;
- 为数据创建HTML表单元素;
- 接收和处理用户从客户端提交的表单及数据。
二、form表单的基本语法
编写Django的form表单,非常类似我们在模型系统里编写一个模型。在模型中,一个字段代表数据表的一列,而form表单中的一个字段代表<form>
中的一个<input>
元素。
1. form表单类的书写
在app文件夹下,新建一个forms.py
文件写入:
from django import formsclass MyForm(forms.Form):# 最多不能超过20个字符,最少5个字符username = forms.CharField(max_length=20, min_length=5)password = forms.CharField(max_length=20, min_length=5)# 会验证输入是否符合邮箱格式email = forms.EmailField()
Form类中的每个字段不仅会验证数据,还会将数据转换为合适的格式。比如,DateField
类型的字段会将收到的数据转换为python的datetime.data
对象,无论我们传给它的是对象还是字符串,只要是有效的,它都会转换为datetime.data
对象。
2. 校验数据
在终端中运行命令python manage.py shell
,导入表单类,就可以在终端中进行以下步骤。
创建表单对象:
实例化表单类,参数为一个字典,键为类属性,值为需要提交的数据。form_obj1 = MyForm({'username':'mahugh','password':'123456','email':'123456'}) # email的值不符合邮箱格式form_obj2 = MyForm({'username':'mahugh','password':'123456','email':'123456@qq.com'}) # 所有值都符合条件
查看验证是否通过:
is_valid()
方法,只要有一个键值对不符合验证条件,就返回false。传入多余的键值对,不会影响验证结果,但少传键值对就会返回false。
form_obj1.is_valid() # 返回:Falseform_obj2.is_valid() # 返回:True
查看通过验证的数据:
cleaned_data
只包含合法的(符合验证条件的)数据,多出的和不合法(不符合验证条件的)都不会被包含。form_obj1.cleaned_data # 返回:{'username': 'mahugh', 'password': '123456'}form_obj2.cleaned_data # 返回:{'username': 'mahugh', 'password': '123456', 'email': '123456@qq.com'}
未调用
is_valid()
方法进行验证的form表单对象,调用cleaned_data
属性查看正确的数据时,会报错:'xxx' object has no attribute 'form_true'
。查看未通过验证的错误信息:
errors
只包含不合法数据的错误信息,多出的和合法的都不会被包含。form_obj1.errors # 返回:<ul class="errorlist"><li>email<ul class="errorlist"><li>输入一个有效的 Email 地址。</li></ul></li></ul>
errors
会被渲染成无序列表。
3. 渲染表单标签
视图中,生成一个表单对象,传递给模板:
def index(request):form_obj = MyForm(auto_id=True)return render(request, 'index.html', {'form_obj':form_obj})
如果 auto_id
设置为 True,那么表单输出将包括 <label>
标签,并将使用字段名作为每个表单字段的 id属性值,否则,不输出 <label>
标签,不设置id属性。
在模板文件中,写入变量:
<form action="" method="post">{{ form_obj }}
</form>
这样就会将所有表单字段渲染为input框,并渲染label提示信息。提示信息默认为首字母大写的字段名称。但这种方法,过于死板,所以不常用。先看一些高级语法,之后总结常用写法。
高级语法:
只渲染指定表单字段为input框,不渲染提示信息:
{{ form_obj.username }}
或者,使用循环渲染所有字段为input框:
{% for obj in form_obj %}<!-- obj渲染出来只是一个个的input框 -->{{ obj }} {% endfor %}
只渲染指定字段的提示信息,不渲染input框:
{{ form_obj.username.label }}
如果想自定义提示信息,可以在表单类中,传入label参数:
class MyForm(forms.Form):username = forms.CharField(max_length=20, min_length=5, label='姓名')
这样,提示信息就会变成“姓名”了,而不是“Username”。
使用指定的标签,包裹住字段被渲染后的html代码:
<!-- 比如,以p标签包裹username字段 --> {{ form_obj.username.as_p }}
最终渲染的html代码如下:
<p><label for="id_username">姓名</label> <input type="text" name="username" maxlength="20" minlength="5" required="" id="id_username"> </p>
django支持的标签还有:
<!-- 渲染为无序列表,以li标签进行包裹 --> {{ form_obj.as_ul }}<!-- 渲染为表格,必须放在table标签内 --> {{ form_obj.as_table }}
三、展示错误信息
测试准备:由于浏览器自带一些简单且容易跳过的验证措施,会干扰我们后端的测试验证,所以先在form标签中设置
novalidate
属性,来跳过浏览器验证。
1. 展示错误信息
首先在视图中使用
is_valid()
方法,验证后端提交的数据是否合法。合法就做后续步骤,不合法就将页面重新渲染一遍:def login_view(self, request):# request.POST可以看作是一个字典,因此可以直接用来实例化表单对象form_obj = MyForm(request.POS, auto_id=True)if form_obj.is_valid():return HttpResponse('好耶!验证通过了!')else:# 带着错误信息,再渲染一遍return render(request, 'index.html', context={'form_obj': form_obj})
不要忘记
auto_id=True
参数!然后在模板的合适位置,写入错误信息变量:
<form action="" method="post" novalidate>{% for form_obj in reg_form %}<label for="{{ form_obj.auto_id }}">{{ form_obj.label }}:</label>{{ form_obj }}{% if form_obj.errors %}{% for error in form_obj.errors %}<div>{{ error }}</div>{% endfor %}{% endif %}{% endfor %}
{{ form_obj.auto_id }}
返回字段input框的id属性值,前提是实例化form表单对象时,写了auto_id=True
参数。
因为{{ form_obj.errors }}
默认是一个无序列表,使用for循环可以更好的展示多条错误信息。
也可以写作{{ form_obj.errors.0 }}
,只获取错误信息的字符串,不显示 • 符号。
2. 自定义错误信息
在表单类的字段中,传入error_messages
参数,该参数接收一个字典:
class MyForm(forms.Form):username = forms.CharField(max_length=20, min_length=5,error_messages={'max_length': '最多不能超过20个字符','min_length': '最少不能少于5个字符','required': '这个东西必须给我回答,不然揍你!'})# 邮箱比较特殊,需要单独记忆email = forms.EmailField(label='邮箱', error_messages={'invalid': '这™是邮箱?'})
字典当中的键称为“错误信息键”,值为验证失败时提示的错误信息。
required
错误信息键,指在设置了required=True
时(表示该字段必须填写),没有填写信息,就会提示该键后面的提示信息。
invalid
则会在字段自带的验证未通过时,提示后面的信息,比如在上面的例子中,如果填写的不是一个邮箱,则会提示:“这™是邮箱?”。
不同的字段,拥有不同的错误信息键。常用的错误信息键会在字段 参数和类型 中讲到。
3. 动态添加错误信息
add_error()
方法向表单特定字段添加错误信息。
form_obj.add_error('字段名', 错误信息)
字段的名称如果为None,error将作为Form.non_field_errors()
的一个非字段错误。
错误信息可以是一个字符串,或者最好是 ValidationError 的实例,如:ValidationError("用户名已存在")
。
注意:Form.add_error()
会自动从 cleaned_data 中删除相关字段。
四、form表单的钩子函数(HOOK)
钩子函数是一类有特殊用法的函数,它会在特定节点自动触发完成响应操作。分为局部钩子函数和全局钩子函数两类。
1. 局部钩子(只涉及到一个字段)
局部钩子函数的函数名就是clean_字段名
,你要给那个字段自定义规则,这个字段名就是谁!
比如:在django表单进行验证时,检查用户名是否含有违规字词(只涉及到username字段):
from django import forms
from django.core.exceptions import ValidationError
from app01.models import UserInfoclass MyForm(forms.Form):# 表单字段username = forms.CharField(label='用户名', max_length=12, min_length=2)# 局部钩子def clean_name(self):# 获取用户输入的用户名val = self.cleaned_data.get('username')# 查看数据库中是否有这个值ret = UserInfo.objects.filter(username=val) # 如果在数据库中没有,就通过匹配if not ret: return val# 否则,说明在数据库中有该用户名else:raise ValidationError("用户名已存在")
2. 全局钩子(涉及到多个字段)
全局钩子的函数名必须是clean()
!
比如:在django表单进行验证时,检查两次用户密码是否一致(涉及到password和confirm_password两个字段):
from django import forms
from django.core.exceptions import ValidationError
from app01.models import UserInfoclass MyForm(forms.Form):# 表单字段password = forms.CharField(label='密码', max_length=18, min_length=6)confirm_password = forms.CharField(label='确认密码', max_length=18, min_length=6)# 全局钩子def clean(self):pwd=self.cleaned_data.get("password") r_pwd=self.cleaned_data.get("confirm_password")# 上面两个,有可能自带规则或自定义规则未通过,则get取值是空if pwd and r_pwd: # 如果两个都通过了第一层说明clean_data中有值就是trueif pwd==r_pwd:return self.cleaned_dataelse:raise ValidationError("两次密码不一致")else: '''如果两个只要有其中一个不在clean_data里,那就没必要在比较了,因为本身就已经在errors里了'''return self.cleaned_data
五、字段参数和类型
1. 核心参数
label
:用来自定义表单的提示信息(label标签的文本)。error_messages
:用于自定义验证不通过时的提示信息,在上面的自定义错误信息一节中已经讲过。initial
:用来给字段设置默认值,对应input标签的value属性。required
:指定该字段是否是必须填写的,默认值为true
,表示该字段必须填写,否则不能通过验证。
widget
参数
为字段指定一个Widget类,它有以下作用:
指定部件,对应的是input的type属性:
widget=forms.TextInput # 普通文本类型 widget=forms.PasswordInput # 密码类型 widget=forms.EmailInput # 邮箱类型
较为复杂的部件:
单选按钮
RadioSelect
(对应radio):gender = forms.fields.ChoiceField(choices=((1, "男"), (2, "女"), (3, "保密")),label="性别",initial=3,widget=forms.RadioSelect() )
选择框
CheckboxInput
(对应checkbox):# 单选框 keep = forms.ChoiceField(label="是否记住密码",initial="checked",widget=forms.CheckboxInput() )# 多选框 hobby = forms.MultipleChoiceField(choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),label="爱好",initial=[1, 3],widget=forms.CheckboxSelectMultiple() )
下拉框
CheckboxInput
(对应option):# 单选下拉框 hobby = forms.ChoiceField(choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),label="爱好",initial=3,widget=forms.Select() )# 多选下拉框 hobby = forms.MultipleChoiceField(choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),label="爱好",initial=[1, 3],widget=forms.SelectMultiple() )
更多内置部件参考官方文档:传送门
传入参数,多用于设置标签的属性值:
比如设置class
属性,使用attrs
参数:widget=forms.TextInput(attrs={'class': 'c1 c2 c3'} )
validators
参数
给字段提供一个验证函数列表,用于自定义验证规则:
from django.core.exceptions import ValidationError# 这个东西是用来翻译东西的
from django.utils.translation import gettext_lazy as _def check_username(value):# 阿巴阿巴,验证操作……if 阿巴阿巴:# 验证不通过,抛出异常raise ValidationError(# 错误信息,翻译用不用看你自己_('%(value)这玩意得这个样子才行'),params={'value': value},)class MyForm():username = forms.CharField(validators=[check_username])
之后,username
字段就会使用check_username
函数进行验证。django还自带了一些验证器,比如RegexValidator
验证器可以帮助我们通过正则表达式,快速书写验证方法:
validators=[# 参数为正则表达式和错误信息RegexValidator(r'我是正则表达式', '你这玩意不符合我这个正则表达式啊')]
更多内置验证器参考官方文档:传送门
其他参数
help_text=''
: 帮助信息(在标签旁边显示)localize=False
:是否支持本地化disabled=False
:是否可以编辑label_suffix=None
:Label内容后缀
2. 常用类型
BooleanField
:- 默认部件:
CheckboxInput
- 空值:
False
- 规范化为:Python 的
True
或False
值。 - 如果字段有
required=True
,则验证该值是否为True
(例如,复选框被选中)。 - 错误信息键:
required
- 默认部件:
CharField
:默认部件:
TextInput
空值:
empty_value
的值。规范化为:一个字符串。
如果提供了
max_length
和min_length
,则验证输入的字符数。否则,所有输入都有效。错误信息键:
required
、max_length
、min_length
。可选参数:
max_length
:最大字符数。min_length
:最小字符数。strip
:如果True
(默认),该值将被去掉前面和末尾的空白。empty_value
:用来表示“空”的值。默认为空字符串。
IntegerField
:当
Field.localize
为False
时是NumberInput
否则,该字段的默认表单部件是TextInput
否则,该字段的默认表单部件是TextInput
。空值:
None
规范化为:Python 的整数。
验证给定值是否为整数。
错误信息键:
required
、invalid
、max_value
、min_value
。可选参数:
max_value
:最大值。min_value
:最小值。
DecimalField
:当
Field.localize
为False
时是NumberInput
否则,该字段的默认表单部件是TextInput
。空值:
None
规范化为:Python 的
decimal
。验证给定值是否为十进制。如果提供了
max_value
和min_value
,则额外验证值的范围。前面和后面的空格会被忽略。错误信息键:
required
、invalid
、max_value
、min_value
、max_digits
、max_decimal_places
、max_whole_digits
。可选的参数:
max_value=None
:最大值。
min_value=None
:最小值。max_digits
:最大数字总位数。decimal_places
:小数位数。
DateField
:默认部件:
DateInput
空值:
None
规范化为:Python 的
datetime.date
对象。验证给定值是
datetime.date
、datetime.datetime
或以特定日期格式化的字符串。格式:“2015-09-01”
错误信息键:
required
、invalid
。可选的参数:
input_formats
:用于将字符串转换为有效的datetime.date
对象的格式列表,使用的是time模块的那一套格式化方法。
TimeField
:与
DateField
基本相同,只有格式不同:“11:12”DateTimeField
:与
DateField
基本相同,只有格式不同:“2015-09-01 11:12”EmailField
:默认部件:
EmailInput
空值:empty_value` 的值。
规范化为:一个字符串。
使用
EmailValidator
来验证给定的值是一个有效的电子邮件地址,使用一个适度复杂的正则表达式。错误信息键:
required
、invalid
:输入内容不符合邮箱格式时提示的错误信息。可选参数:
max_length
、min_length
和empty_value
,它们的工作原理与CharField
一样。
FileField
:默认部件:
ClearableFileInput
空值:
None
规范化为:一个
UploadedFile
对象,它将文件内容和文件名包装成一个单一对象。可以验证非空文件数据已经绑定到表单中。
错误信息键:
required
、invalid
、missing
、empty
、max_length
。可选的验证参数:
max_length
:文件名的最大长度。allow_empty_file
:是否允许文件内容为空。
更多表单字段类型参考官方文档:传送门
django2.2-form表单详解相关推荐
- HTML第三章 form表单(详解,内含详细代码示例)
目录 1.特点 2. 表单的语法和属性 3. input元素 4. select和下拉选择框 5. textarea多行文本域 6.label关联控件 每日一句 1.特点 提供了一些可视化的输入控件 ...
- Form 表单详解:案例、CSS 美化
本文要点: 常见表单 表单的性质 表单CSS美化 使用 radio 实现 Tab 选项卡 什么是表单 用户通过表单填写信息,然后通过计算机网络传送给服务器.表单标签不是一个标签,而是一组标签,因为不同 ...
- js入门·表单详解一(修改表单属性,修改表单元素值)
实在javascript入门·Document对象入门讲解(访问表单,创建新页,获取页标题) 一文中,我们已经把表单的一些基本访问等弄清楚了,下面我们深入的学下表单的属性以及对表单元素的简单操作! 演 ...
- form提交后台注解拿不到数据_Form表单详解
主要内容Form表单.表单元素.表单元素的属性.HTML5新增type类型和HTML新增属性 知乎视频www.zhihu.com 知乎视频www.zhihu.com 知乎视频www.zhihu. ...
- 菜鸟教程:HTML表单详解
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.表单元素form 二.form元素的属性 1.action 2.method 3.enctype 4.注意事项 三 ...
- layui单选框verify_layui lay-verify form表单自定义验证规则详解
虽然layui的官方文档已经是写的比较详细,但是初次使用的时候总会懵一下,这里纪录一下lay-verify自定义验证规则的时候到底放哪. html: 提交 js: form.verify({ //数组 ...
- form表单提交三种方式,demo实例详解
第一种:使用type=submit 可以直接提交 <html><head><title>submit直接提交</title></head>& ...
- 微信小程序form表单提交到MYSQL实例详解(PHP)
1.小程序相对于之前的WEB+PHP建站来说,个人理解为只是将web放到了微信端,用小程序固定的格式前前端进行布局.事件触发和数据的输送和读取,服务器端可以用任何后端语言写,但是所有的数据都要以JSO ...
- django之Form表单
HTML表单 在HTML中,表单是<form>...</form> 之间元素的集合,它们允许访问者输入文本.选择选项.操作对象和控制等等,然后将信息发送回服务器. 某些表单的元 ...
- html表单怎么设置编码,form 表单 设置编码和页面编码
var isIE=!!window.ActiveXObject; if(isIE && document.charset!="utf-8")location.rel ...
最新文章
- mysql 绿色版远程访问_【Linux】MySQL解压版安装及允许远程访问
- java中bean文件主要实现内容_JavaBean简单及使用
- 指针的运用与strcpy函数的优化
- 一份字节跳动面试官给你的Java技术面试指南,彻底帮你搞懂
- UVa 11307 - Alternative Arborescence(dp)
- Leetcode 213. 打家劫舍 II (每日一题 20211009)
- YOLO学习-3:ubuntu16.04+ yolov3(darknet)+GPU(nvidia 1080ti)+opencv2.4.11 摄像头测试实践
- boost::stable_sort相关的测试程序
- Java多线程(十)之ReentrantReadWriteLock深入分析
- Js中Currying的应用
- 机器学习笔记2 – sklearn之iris数据集
- TYVJ P1073 加分二叉树 Label:区间dp
- 全球唯一标识符 System.Guid.NewGuid().ToString()
- 在线订餐系统php心得体会_基于php的网上订餐系统的设计与实现论文.doc
- docker 权限问题 Got permission denied while trying to connect to the Docker daemon socket at 。。。
- 复制移动VMware Workstation虚拟机文件产生的问题【转】
- php发送邮件功能(以QQ邮件为例)
- 一个IP账号,为啥通过路由器就可供多人同时使用?
- 命名实体识别的一点经验与技巧
- [SugerTangYL] 简易电子时钟Verilog设计
热门文章
- java 子类 继承父类的注解,spring使用注解通过子类注入父类的私有变量
- c语言实现16位定点数乘法,c语言 fixed-point 定点数 运算
- android播放器 重音,如何在SQLite查询中忽略重音(Android)
- android合入第三方库,Android中inflate和merge结合使用
- java模拟http_java模拟http请求的错误问题整理
- Windows下Nginx的启动、停止、重启等命令
- git合并分支,发布代码
- 声明,本博客文章均为转载,只为学习,不为其他用途。感谢技术大牛的技术分享,让我少走弯路。...
- Handler机制原理图、源码、使用!!!!!
- flask页面中Head标签内容为空问题