Django组件-Forms组件
Django的Forms组件主要有以下几大功能:
页面初始化,生成HTML标签
校验用户数据(显示错误信息)
HTML Form提交保留上次提交数据
form组件的基本使用
from django import forms
class EmpForm ( forms. Form) :
name = forms. CharField( min_length= 4 , label= "姓名" , error_messages= { "min_length" : "你太短了" , "required" : "该字段不能为空!" } )
age = forms. IntegerField( label= "年龄" )
salary = forms. DecimalField( label= "工资" )
from django. urls import path
from app01 import views
urlpatterns = [
path( 'add_emp/' , views. add_emp) ,
]
from app01. My_Forms import EmpForm
def add_emp ( request) :
if request. method == "GET" :
form = EmpForm( )
return render( request, "add_emp.html" , { "form" : form} )
else :
form = EmpForm( request. POST)
if form. is_valid( ) :
data = form. cleaned_data
print ( data)
else :
print ( form. errors)
return render( request, "add_emp.html" , { "form" : form} )
模板文件
方式一 : 手动写HTML < form action = " " method = " post" >
{% csrf_token %}
< p> 姓名:< input type = " text" name = " name" > </ p>
< p> 年龄:< input type = " text" name = " age" > </ p>
< p> 工资:< input type = " text" name = " salary" > </ p>
< input type = " submit" >
</ form>
通过form对象的as_p方法实现 < form action = " " method = " post" novalidate >
{% csrf_token %}
{{ form.as_p }}
< input type = " submit" >
</ form>
手动获取form对象的字段 < form action = " " method = " post" novalidate >
{% csrf_token %}
< div>
< label for = " id_{{ form.name.name }}" > {{ form.name.label }}</ label>
{{ form.name }} < span> {{ form.name.errors.0 }}</ span>
</ div>
< div>
< label for = " id_{{ form.age.name }}" > {{ form.age.label }}</ label>
{{ form.age }} < span> {{ form.age.errors.0 }}</ span>
</ div>
< div>
< label for = " id_salary" > {{ form.r_salary.label }}</ label>
{{ form.salary }} < span> {{ form.salary.errors.0 }}</ span>
</ div>
< input type = " submit" >
</ form>
用for循环展示所有字段 , 循环的是form对象中的字段值 < form action = " " method = " post" novalidate >
{% csrf_token %}
{% for field in form %}
< div>
< label for = " id_{{ field.name }}" > {{ field.label }}</ label>
{{ field }} < span> {{ field.errors.0 }}</ span>
</ div>
{% endfor %}
< input type = " submit" >
</ form>
附:Django内置的字段及属性
Field
required= True , 是否允许为空
widget= None , HTML插件
label= None , 用于生成Label标签或显示内容
initial= None , 初始值
help_text= '' , 帮助信息( 在标签旁边显示)
error_messages= None , 错误信息 { 'required' : '不能为空' , 'invalid' : '格式错误' }
show_hidden_initial= False , 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
validators= [ ] , 自定义验证规则
localize= False , 是否支持本地化
disabled= False , 是否可以编辑
label_suffix= None Label内容后缀
CharField( Field)
max_length= None , 最大长度
min_length= None , 最小长度
strip= True 是否移除用户输入空白
IntegerField( Field)
max_value= None , 最大值
min_value= None , 最小值
FloatField( IntegerField)
. . .
DecimalField( IntegerField)
max_value= None , 最大值
min_value= None , 最小值
max_digits= None , 总长度
decimal_places= None , 小数位长度
BaseTemporalField( Field)
input_formats= None 时间格式化
DateField( BaseTemporalField) 格式:2015 - 09 - 01
TimeField( BaseTemporalField) 格式:11 : 12
DateTimeField( BaseTemporalField) 格式:2015 - 09 - 01 11 : 12
DurationField( Field) 时间间隔:% d % H: % M: % S. % f
. . .
RegexField( CharField)
regex, 自定制正则表达式
max_length= None , 最大长度
min_length= None , 最小长度
error_message= None , 忽略,错误信息使用 error_messages= { 'invalid' : '...' }
EmailField( CharField)
. . .
FileField( Field)
allow_empty_file= False 是否允许空文件
ImageField( FileField)
. . .
注:需要PIL模块,pip3 install Pillow
以上两个字典使用时,需要注意两点:
- form表单中 enctype= "multipart/form-data"
- view函数中 obj = MyForm( request. POST, request. FILES)
URLField( Field)
. . .
BooleanField( Field)
. . .
NullBooleanField( BooleanField)
. . .
ChoiceField( Field)
. . .
choices= ( ) , 选项,如:choices = ( ( 0 , '上海' ) , ( 1 , '北京' ) , )
required= True , 是否必填
widget= None , 插件,默认select插件
label= None , Label内容
initial= None , 初始值
help_text= '' , 帮助提示
ModelChoiceField( ChoiceField)
. . . django. forms. models. ModelChoiceField
queryset,
empty_label= "---------" ,
to_field_name= None ,
limit_choices_to= None
ModelMultipleChoiceField( ModelChoiceField)
. . . django. forms. models. ModelMultipleChoiceField
TypedChoiceField( ChoiceField)
coerce = lambda val: val 对选中的值进行一次转换
empty_value= '' 空值的默认值
MultipleChoiceField( ChoiceField)
. . .
TypedMultipleChoiceField( MultipleChoiceField)
coerce = lambda val: val 对选中的每一个值进行一次转换
empty_value= '' 空值的默认值
ComboField( Field)
fields= ( ) 使用多个验证,如下:即验证最大长度20 ,又验证邮箱格式
fields. ComboField( fields= [ fields. CharField( max_length= 20 ) , fields. EmailField( ) , ] )
MultiValueField( Field)
PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用
SplitDateTimeField( MultiValueField)
input_date_formats= None , 格式列表:[ '%Y--%m--%d' , '%m%d/%Y' , '%m/%d/%y' ]
input_time_formats= None 格式列表:[ '%H:%M:%S' , '%H:%M:%S.%f' , '%H:%M' ]
FilePathField( ChoiceField) 文件选项,目录下文件显示在页面中
path, 文件夹路径
match= None , 正则匹配
recursive= False , 递归下面的文件夹
allow_files= True , 允许文件
allow_folders= False , 允许文件夹
required= True ,
widget= None ,
label= None ,
initial= None ,
help_text= ''
GenericIPAddressField
protocol= 'both' , both, ipv4, ipv6支持的IP格式
unpack_ipv4= False 解析ipv4地址,如果是: : ffff: 192.0 .2 .1 时候,可解析为192.0 .2 .1 , PS:protocol必须为both才能启用
SlugField( CharField) 数字,字母,下划线,减号(连字符)
. . .
UUIDField( CharField) uuid类型
. . .
Django内置字段
局部钩子和全局钩子
from django import forms
from django. core. exceptions import ValidationError
from app01 import models
class EmpForm ( forms. Form) :
name = forms. CharField( min_length= 5 , label= "姓名" , error_messages= { "required" : "该字段不能为空!" ,
"min_length" : "用户名太短。" } )
age = forms. IntegerField( label= "年龄" )
salary = forms. DecimalField( max_digits= 5 , decimal_places= 2 , label= "工资" )
r_salary = forms. DecimalField( max_digits= 5 , decimal_places= 2 , label= "请再输入工资" )
def clean_name ( self) :
val = self. cleaned_data. get( "name" )
if val. isdigit( ) :
raise ValidationError( "用户名不能是纯数字" )
elif models. Emp. objects. filter ( name= val) :
raise ValidationError( "用户名已存在!" )
else :
return val
def clean ( self) :
val = self. cleaned_data. get( "salary" )
r_val = self. cleaned_data. get( "r_salary" )
if val == r_val:
return self. cleaned_data
else :
raise ValidationError( "请确认工资是否一致。" )
def add_emp ( request) :
if request. method == "GET" :
form = EmpForm( )
return render( request, "add_emp.html" , { "form" : form} )
else :
form = EmpForm( request. POST)
if form. is_valid( ) :
data = form. cleaned_data
data. pop( "r_salary" )
models. Emp. objects. create( ** data)
return redirect( "/index/" )
else :
clear_errors = form. errors. get( "__all__" )
return render( request, "add_emp.html" , { "form" : form, "clear_errors" : clear_errors} )
< form action = " " method = " post" novalidate >
{% csrf_token %}
< div>
< label for = " id_{{ form.name.name }}" > 姓名</ label>
{{ form.name }} < span> {{ form.name.errors.0 }}</ span>
</ div>
< div>
< label for = " id_{{ form.age.name }}" > 年龄</ label>
{{ form.age }} < span> {{ form.age.errors.0 }}</ span>
</ div>
< div>
< label for = " id_salary" > 工资</ label>
{{ form.salary }} < span> {{ form.salary.errors.0 }}{{ clear_errors.0 }}</ span>
</ div>
< div>
< label for = " id_r_salary" > 请再输入工资</ label>
{{ form.r_salary }} < span> {{ form.r_salary.errors.0 }}{{ clear_errors.0 }}</ span>
</ div>
< input type = " submit" >
</ form>