django表单使用
一、表单常用字段类型及参数
表单可以自动生成html代码,每一个字段默认有一个html显示样式,大多数默认为输入框。
字段相当于正则表达式的集合,能够对表单传入的数据进行校验,并且某一部分校验失败时会保留另一部分校验成功的值。
使用表单时首先需要导入forms模块和forms的fields模块,再定义一个继承forms.Form的类,实例化后在模板中通过调用实例化对象的属性生成输入框。
field:这个一般不直接使用,用于被其他字段继承
required=True, 是否允许为空
label=None, 用于生成显示内容,如果不定义label,则显示的内容为首字母大写的字段名
initial=None, 初始值
help_text='', 帮助信息(在标签旁边显示)
error_messages=None, 例如 {'required': '不能为空', 'invalid': '格式错误'},是一个字典,key表示每一个表达式的code,value表示如果在对应的code上发生错误,后台可以捕捉到的错误信息并返给前台与用户交互,其中value又是一个列表
show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
validators=[], 自定义验证规则
localize=False, 是否支持本地化
disabled=False, 是否可以编辑
label_suffix=None Label内容后缀
widget=None, 生成HTML插件
1.BooleanField(Field):布尔值,相当于单选框
2.CharField(Field):字符串
max_length最大长度,min_length最小长度,strip是否移除用户输入的空格
3.EmailField(CharField):邮箱
invalid格式是否合法
4.IntegerField(Field):整数
invalid格式是否合法、max_value最大值、min_value最小值
5.FloatField(IntegerField):浮点类型
6.DecimalField(IntegerField):浮点类型
max_digits(总长度)、decimal_places(小数位长度)
7.FileField(Field):上传文件、ImageField(Field)上传图片
allow_empty_file是否允许空文件,上传文件需要在form表单指定enctype="multipart/form-data",并且要通过request.FILES接收
upload_to:指定上传路径
8.ChoiceField(Field):单选下拉列表
9.MultipleChoiceField(ChoiceField):多选下拉列表
10.TypedChoiceField(ChoiceField))
可对传入的数据进行一次类型转化coerce = lambda x: int(x)
11.GenericIPAddressField(CharField):ip地址
protocol='both'表示同时支持ipv4和ipv6的地址
12.DateField(BaseTemporalField),日期,2019-05-10,
13.TimeField(BaseTemporalField),时间,14:23
14.DateTimeField(BaseTemporalField),日期和时间,2019-05-10 14:23
15.URLField:接收URL格式的字符串
二、django内置插件
使用django的内置html插件时,需要先导入forms模块的widgets模块,from django.forms import widgets。
对于CharField字段,默认显示的是文本框,如果希望显示成单选、多选或下拉列表的形式,则需要用到widgets定制插件。
TextInput(Input)
EmailInput(TextInput)
NumberInput(TextInput)
RadioSelect(ChoiceWidget)
Select(ChoiceWidget)
SelectMultiple(Select)
CheckboxInput(Input)
CheckboxSelectMultiple(ChoiceWidget)
Textarea(Widget)
DateInput(DateTimeBaseInput)
DateTimeInput(DateTimeBaseInput)
TimeInput(DateTimeBaseInput)
URLInput(TextInput)
PasswordInput(TextInput)
FileInput
HiddenInput(TextInput)
NullBooleanSelect
ClearableFileInput
MultipleHiddenInput
SplitDateTimeWidget
SplitHiddenDateTimeWidget
SelectDateWidget
1.定制单选radio、单选下拉列表、多选下拉列表、单选框和多选框:通过CharField、ChoiceField和MutipleChoiceField字段
对于单选radio,第一种写法使用CharField字段,该字段默认显示为输入框,通过widget=widgets.RadioSelect插件定制为单选框样式,并将choices作为参数传递给该插件。
第二种写法使用ChoiceField字段,该字段默认显示为下拉列表,通过widget=widgets.RadioSelect插件定制为单选框样式,并将choices作为参数传递给该字段。
通过widgets定制插件时,可同时给字段加上自定义属性,例如如下hobby8和hobby9。
#单选radio
hobby1 = fields.CharField(label='爱好1',widget=widgets.RadioSelect(choices=((1,'篮球'),(2,'足球'),(3,'乒乓球'))),initial=1)
hobby2 = fields.ChoiceField(label='爱好2',widget=widgets.RadioSelect,choices=((1,'篮球'),(2,'足球'),(3,'乒乓球')),initial=1)
#单选下拉列表
hobby3 = fields.CharField(label='爱好3',widget=widgets.Select(choices=((1,'篮球'),(2,'足球'),(3,'乒乓球'))),initial=3)
hobby4 = fields.ChoiceField(label='爱好4', widget=widgets.Select,choices=((1, '篮球'), (2, '足球'), (3, '乒乓球')), initial=3)
#多选下拉列表
hobby5 = fields.CharField(label='爱好5', widget=widgets.SelectMultiple(choices=((1, '篮球'), (2, '足球'), (3, '乒乓球'))), initial=[1, 2])
hobby6 = fields.MultipleChoiceField(label='爱好6', widget=widgets.SelectMultiple,choices=((1, '篮球'), (2, '足球'), (3, '乒乓球')), initial=[1,2])
#单选框
hobby7 = fields.CharField(label='是否同意',widget=widgets.CheckboxInput())
#多选框
hobby8 = fields.CharField(label='爱好8', widget=widgets.CheckboxSelectMultiple(choices=((1, '篮球'), (2, '足球'), (3, '乒乓球')),attrs={'name':'hobby8'}), initial=[1, 2])
hobby9 = fields.MultipleChoiceField(label='爱好9',widget=widgets.CheckboxSelectMultiple(attrs={'name':'hobby9'}),choices=((1, '篮球'), (2, '足球'), (3,'乒乓球'),initial=[1, 2])
定制radio、select和checkbox
2.扩展正则
如果某一字段自带的验证方法不足以进行验证,可以自定义验证方法,这需要通过RegexField字段或者validators=[]参数完成
#单选radio
hobby1 = fields.CharField(label='爱好1',widget=widgets.RadioSelect(choices=((1,'篮球'),(2,'足球'),(3,'乒乓球'))),initial=1)
hobby2 = fields.ChoiceField(label='爱好2',widget=widgets.RadioSelect,choices=((1,'篮球'),(2,'足球'),(3,'乒乓球')),initial=1)
#单选下拉列表
hobby3 = fields.CharField(label='爱好3',widget=widgets.Select(choices=((1,'篮球'),(2,'足球'),(3,'乒乓球'))),initial=3)
hobby4 = fields.ChoiceField(label='爱好4', widget=widgets.Select,choices=((1, '篮球'), (2, '足球'), (3, '乒乓球')), initial=3)
#多选下拉列表
hobby5 = fields.CharField(label='爱好5', widget=widgets.SelectMultiple(choices=((1, '篮球'), (2, '足球'), (3, '乒乓球'))), initial=[1, 2])
hobby6 = fields.MultipleChoiceField(label='爱好6', widget=widgets.SelectMultiple,choices=((1, '篮球'), (2, '足球'), (3, '乒乓球')), initial=[1,2])
#单选框
hobby7 = fields.CharField(label='是否同意',widget=widgets.CheckboxInput())
#多选框
hobby8 = fields.CharField(label='爱好8', widget=widgets.CheckboxSelectMultiple(choices=((1, '篮球'), (2, '足球'), (3, '乒乓球')),
attrs={'name':'hobby7'}), initial=[1, 2])
hobby9 = fields.MultipleChoiceField(label='爱好9',widget=widgets.CheckboxSelectMultiple(attrs={'name':'hobby8'}),
choices=((1, '篮球'), (2, '足球'), (3,'乒乓球'),initial=[1, 2])
定制radio、select和checkbox
通过validators=[]属性定制时,可以自定义多个规则RegexValidator,每一个规则的第一个参数为规则,第二个规则为对应的错误信息
通过RegexField字段定制时,只能定制一个规则。
三、表单使用实例
1.forms的py文件
class UserForm(forms.Form):
username = fields.CharField(label='姓名',required=True,max_length=15,error_messages={'max_length':'too long'})
age = fields.IntegerField(label='年龄',required=True,min_value=18,error_messages={'invalid':'请输入整数','min_value':'不符合劳动法'})
birth = fields.DateField(label='入职时间',required=True)
email = fields.EmailField(label='邮箱',required=True,error_messages={'invalid':'请输入有效格式的邮箱'})
gender = fields.CharField(label='性别', widget=widgets.RadioSelect(choices=((1, '男'), (2, '女'))), initial=1)
resume = fields.FileField(label='简历')
city = fields.CharField(label='省份',widget=widgets.Select())
hobby = fields.MultipleChoiceField(label='爱好',widget=widgets.CheckboxSelectMultiple(attrs={'name':'hobby8'}),
choices=((1, '篮球'), (2, '足球'), (3, '乒乓球')),initial=[1,2])
proto = fields.CharField(label='是否已阅协议', widget=widgets.CheckboxInput())
def __init__(self,*args,**kwargs):
super(UserForm,self).__init__(*args,**kwargs)
self.fields['city'].widget.choices = Province.objects.all().values_list()
#假设定义了一个省份的类存放在数据库,为了数据库的内容变化能在页面刷新时显示到页面上,需要进行init操作并将数据库的值赋值给city字段
定义UserForm
2.处理函数的py文件
def add_user(request):
if request.method == 'GET':
obj = UserForm() #实例化一个空的表单
return render(request,'add_user.html',{'obj':obj})
elif request.method =='POST':
obj = UserForm(request.POST,request.FILES) #传入的文件需要通过request.FILES接收,其他通过request.POST接收,一起传递给表单类进行实例化
if obj.is_valid(): #判断输入是否有效
print(type(obj.fields))
print(obj.fields)
print(type(obj.cleaned_data))
print(obj.cleaned_data) #打印输入内容
print(obj.cleaned_data['username']) #获取输入的username值
print(obj.cleaned_data.get('email')) #获取输入的email值
UserInfo.object.create(**obj.cleaned.data) # UserForm表单对应了数据库中的表UserInfo
else:
print(type(obj.errors))
print(obj.errors.get_json_data())#打印错误信息,如果需要打印错误信息,还需要在form中指定novalidate属性
return render(request,'add_user.html',{'obj':obj})
else:
return redirect('http://www.baidu.com')
处理函数
①obj.is_valid()方法
obj.is_valid()表示判断输入是否满足Form各字段的要求,实例化一个非空的表单,在实例化的时候并没有生成html标签,也没有进行表单验证,生成html标签并且进行表单验证是在is_valid()时进行的。obj.cleaned_data表示键值和对应的输入值。
如果在实例化表单的时候通过inital传值,即obj = UserForm(inital = (request.POST,request.FILES) ),在实例化的时候不会进行表单验证。
②obj.fields属性
obj.fields表示表单的所有字段,类型为<class 'collections.OrderedDict'>。
③obj.cleaned_data属性
在is_valid之前没有cleaned_data,cleaned_data是在进行验证之后才生成,类型为<class 'dict'>
④obj.errors
obj.errors表示错误信息,类型为<class 'django.forms.utils.ErrorDict'>
错误信息默认是以as_ul()进行显示的,其他显示方式还有as_data()、as_json()、as_text()、get_json_Data(),常用get_json_Data()。
3.模板文件
在渲染form对象时,可以以as_table表格、as_ul无序列表、as_p段落等方式进行渲染。
<form action="add_user" method="post" enctype="multipart/form-data"> <!--如果需要上传文件,则form中应指定enctype属性为multipart/form-data-->
{% csrf_token %}
<table>
{{ obj.as_table }} <!--将表单以表格形式渲染-->
</table>
<input type="submit">
</form>
模板文件
页面显示内容为,并且如果按照要求输入数据,pycharm打印的信息如下。
如果在form中指定invalidate属性,假设不输入年龄、不按格式输入邮箱,那么打印的错误信息如下
另外一种模板渲染方式
<form action="add_user" method="post" enctype="multipart/form-data" novalidate>
<!--如果需要上传文件,则form中应指定enctype属性为multipart/form-data-->
{% csrf_token %}
<p>{{ obj.username.label }}{{ obj.username }}{{ obj.errors.0 }}</p>
<p>{{ obj.age.label }}{{ obj.age }}{{ obj.errors.0 }}</p>
<p>{{ obj.birth.label }}{{ obj.birth }}{{ obj.errors.0 }}</p>
<p>{{ obj.email.label }}{{ obj.email }}{{ obj.errors.0 }}</p>
<p>{{ obj.gender.label }}{{ obj.gender }}{{ obj.errors.0 }}</p>
<p>{{ obj.resume.label }}{{ obj.resume }}{{ obj.errors.0 }}</p>
<p>{{ obj.city.label }}{{ obj.city }}{{ obj.errors.0 }}</p>
<p>{{ obj.hobby.label }}{{ obj.hobby }}{{ obj.errors.0 }}</p>
<p>{{ obj.proto.label }}{{ obj.proto }}{{ obj.errors.0 }}</p>
<input type="submit">
</form>
另一种模板渲染方式
四、表单与数据库是否重复验证
上述方法已经可以可以对各字段进行格式、大小、长度等验证,但是表单提交的数据通常要写入数据库,为了防止写入违反唯一性约束的两条相同记录,还需要验证增加的数据是否已经在数据库中存在。
1.对于单一字段
可在表单类时同时定义表单的方法,方法名称为clean_验证字段名,假如上述例子UserForm表单对应了的数据库中的表UserInfo,假如UserInfo表中的username不可重复,那么在定义表单时可通过增加clean_username()方法实现。
#from django.core.exceptions import ValidationError导入异常类
class UserForm(forms.Form):
username = fields.CharField(label='姓名',required=True,max_length=15,error_messages={'max_length':'too long'})
……
def clean_username(self): #定义clean_字段名的方法
v= self.cleaned_data['username'] #
if UserInfo.objects.filter(username=v).count(): #
raise ValidationError('用户名已经存在','repeat') #抛出异常,第一个参数为error_message,第二个为code
return v
表单对单一字段验证
2.对于多个字段
在定义表单类的同时定义clean()方法,假如username和age字段不可同时重复
#from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
class UserForm(forms.Form):
……
def clean(self):
value_dic = self.cleaned_data
v1 = value_dic.get('username')
v2 = value_dic.get('email')
if UserInfo.objects.filter(username=v1,email=v2).count():
raise ValidationError('total error')
return value_dic
表单对多个字段验证
因为这一类错误不属于单一的字段,因此在errors中显示的错误字段为__all__(也即NON_FIELD_ERRORS),而在模板页面只能通过v.non_field_errors(小写)获取整体错误信息,不能通过v.__all__获取。
表单字段类型可参考http://www.cnblogs.com/wupeiqi/articles/6144178.html
django表单使用的更多相关文章
- python 全栈开发,Day111(客户管理之 编辑权限(二),Django表单集合Formset,ORM之limit_choices_to,构造家族结构)
昨日内容回顾 1. 权限系统的流程? 2. 权限的表有几个? 3. 技术点 中间件 session orm - 去重 - 去空 inclusion_tag filter 有序字典 settings配置 ...
- python3之Django表单(一)
1.HTML中的表单 在HTML种,表单是在<form>...</form>种的元素,它允许用户输入文本,选择选项,操作对象等,然后发送这些数据到服务器 表单元素允许用户在表单 ...
- django表单的api
django表单的api,参考文档:https://yiyibooks.cn/xx/Django_1.11.6/ref/forms/api.html 绑定与未绑定形式: Form要么是绑定的,要么是未 ...
- Django表单API详解
声明:以下的Form.表单等术语都指的的广义的Django表单. Form要么是绑定了数据的,要么是未绑定数据的. 如果是绑定的,那么它能够验证数据,并渲染表单及其数据,然后生成HTML表单.如果未绑 ...
- 9:django 表单
django自带表单系统,这个表单系统不仅可以定义属性名,还可以自己定义验证,更有自己自带的错误提示系统 这节我们仅仅粗略的来看一下django表单系统的入门运用(具体的实在太多东西,主要是我觉得有很 ...
- django 表单系统 之 forms.Form
继承forms.Form实现django表单系统 参考: https://www.cnblogs.com/zongfa/p/7709639.html https://www.cnblogs.com/c ...
- 关于创建Django表单Forms继承BaseForm的问题
在创建Django表单时,因为需要验证用户输入的验证码是否正确,因此需要在session里提取当前验证码的值和POST提交过来的值进行比对,如图: form.py from django import ...
- Django 表单处理流程
Django 的表单处理:视图获取请求,执行所需的任何操作,包括从模型中读取数据,然后生成并返回HTML页面(从模板中),我们传递一个包含要显示的数据的上下文.使事情变得更复杂的是,服务器还需要能够处 ...
- 第四章:Django表单 - 2:Django表单API详解
声明:以下的Form.表单等术语都指的的广义的Django表单. Form要么是绑定了数据的,要么是未绑定数据的. 如果是绑定的,那么它能够验证数据,并渲染表单及其数据,然后生成HTML表单.如果未绑 ...
- 第四章:Django表单 - 1:使用表单
假设你想从表单接收用户名数据,一般情况下,你需要在HTML中手动编写一个如下的表单元素: <form action="/your-name/" method="po ...
随机推荐
- 深入理解JVM(③)虚拟机的类加载器(双亲委派模型)
前言 先解释一下什么是类加载器,通过一个类的全限定名来获取描述该类的二进制字节流,在虚拟机中实现这个动作的代码被称为"类加载器(Class Loader)". 类与类加载器 类加载 ...
- GRpc异常处理Filter
全局错误处理服务端 微软已经实施了Interceptors,它们类似于Filter或Middlewares在ASP.NET MVC的核心或的WebAPI,它们可以用于全局异常处理,日志记录,验证等. ...
- JavaWeb项目在浏览器点击几次就阻塞了
问题描述 在学习JavaWeb项目时,通过IDE启动项目后,在浏览器点击几次页面中的链接就阻塞了,浏览器一直转圈圈无法加载,后台日志也没有输出. 第一次遇见这种情况,没有日志完全无法分析到底是什么问题 ...
- java语言基础-start
计算机基础 1.1 计算机以二进制存储数据 十进制数据转成二进制数据:使用除以2获取余数的方式 二进制数据转成十进制数据:使用8421编码的方式 1.2 字节 位(bit):一个数字0或者一个数字1, ...
- UVA1464 Traffic Real Time Query System
传送门:https://www.luogu.com.cn/problem/UVA1464 看到这道题,求必经的点数,还是无向图.那么妥妥的圆方树.圆方树上的任意两圆点间的路径必定是圆点方点相交错的,对 ...
- Face The Right Way思维。。。
题目再次链接 题意: 已知01序列a,求进行定长子串取反的最少操作次数,以及最少时的定长. 分析: 首先,先想一想怎么暴力吧.这样想:要保证最小,那么必然不会对同一个区间反转两次,而在k一定时,则不会 ...
- Report.Net 本地数据库、WebService、Socket报表
本地.服务器的Access.Sql报表编辑.预览.打印. 可自定义预览界面,可方便嵌入到你的程序中去,提供接口函数,如有需要可自行添加接口. 预览采用单双面方式,因为如果页面过多,预览不能全部加载,所 ...
- day38 作业
实现并发的里两种方式 # 第一种 from multiprocessing import Process import time class MyProcess(Process): def run(s ...
- Re5ilio 5ync:资源神器
文章目录 #0x0 简单的介绍 #0x1 安装使用 #0x10 下载 #0x11 安装 #0x12 升级pro权限 #0x13 开始添加资源 #0x14 后续 一定要小心哦!! #0x0 简单的介绍 ...
- .net core微服务——gRPC(下)
序 上一篇博客把grpc的概念说了个大概,介绍了proto的数据类型,基本语法,也写了个小demo,是不是没那么难? 今天要从理论到实际,写两个微服务,并利用grpc完成两者之间的通信.只是作为dem ...