Django中的Form使用时一般有两种功能:
1、生成html标签
2、验证输入内容
要想使用django提供的form,要在views里导入form模块
from django import forms
首先我们创建我们的模版
然后我们来定义一个form 类,以及我们需要掌握的一些基础知识,这些代码全部写在 试图页面里。
from django.shortcuts import render,HttpResponse
from django.forms import widgets
from django.forms import widgets
from django import forms
#创建form表单验证规则
class UserForm(forms.Form):
name = forms.CharField(min_length=4)
pwd = forms.CharField(min_length=6)
r_pwd = forms.CharField(min_length=6)
email = forms.EmailField()
def index(request):
if request.method == 'POST':
form = UserForm(request.POST)
#如果输入全部符合规则判断为真将结果传递给 changed_data,并打印
print('form.is_vaild---------',form.is_valid())
if form.is_valid():
print(form.changed_data)
#如果失败,打印为真的值,打印错误,获取错误字典中name 的错误值。
else:
print(form.cleaned_data)
print('错误信息的类型---------',type(form.errors))
print(form.errors)
print(form.errors.get('name'))
return HttpResponse('ok')
form=UserForm()
return render(request,'index.html',locals())
如果输入正确的验证信息
后台输出
form.is_vaild--------- True
{'name': '召唤精灵', 'pwd': '1111111111', 'r_pwd': '1111111111', 'email': 'asdas@dsad.com'}
可以看出输入符合验证条件的数据, is_vaild 会返回 True ,然后正确信息会存储到cleaned_data 中
下面输入一下错误验证信息
form.is_vaild--------- False
错误信息的类型---------
获取错误信息字典
可以看到类型是已字典到形式存储到,然后咱们通过字典到的取值方法 get 取到验证错误到报错信息。
如果同时有错误有正确会怎么样
form.is_vaild--------- False
{'pwd': '11111111111', 'r_pwd': '1111111111', 'email': 'asdas@dsad.com'}
错误信息的类型---------
获取错误信息字典
虽然验证失败了,但是cleaned_data中保留了正确的验证信息。
创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;
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, # HTML中value的值对应的字段
limit_choices_to=None # ModelForm中对queryset二次筛选
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类型
…
注:UUID是根据MAC以及当前时间等创建的不重复的随机字符串
>>> import uuid
# make a UUID based on the host ID and current time
>>> uuid.uuid1() # doctest: +SKIP
UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
# make a UUID using an MD5 hash of a namespace UUID and a name
>>> uuid.uuid3(uuid.NAMESPACE\_DNS, 'python.org')
UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
# make a random UUID
>>> uuid.uuid4() # doctest: +SKIP
UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
# make a UUID using a SHA-1 hash of a namespace UUID and a name
>>> uuid.uuid5(uuid.NAMESPACE\_DNS, 'python.org')
UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
# make a UUID from a string of hex digits (braces and hyphens ignored)
>>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')
# convert a UUID to a string of hex digits in standard form
>>> str(x)
'00010203-0405-0607-0809-0a0b0c0d0e0f'
# get the raw 16 bytes of the UUID
>>> x.bytes
b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f'
# make a UUID from a 16-byte string
>>> uuid.UUID(bytes=x.bytes)
UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
内直插件
TextInput(Input)
NumberInput(TextInput)
EmailInput(TextInput)
URLInput(TextInput)
PasswordInput(TextInput)
HiddenInput(TextInput)
Textarea(Widget)
DateInput(DateTimeBaseInput)
DateTimeInput(DateTimeBaseInput)
TimeInput(DateTimeBaseInput)
CheckboxInput
Select
NullBooleanSelect
SelectMultiple
RadioSelect
CheckboxSelectMultiple
FileInput
ClearableFileInput
MultipleHiddenInput
SplitDateTimeWidget
SplitHiddenDateTimeWidget
SelectDateWidget
需要给form验证条件,添加 label属性
class UserForm(forms.Form):
name = forms.CharField(min_length=4,label='用户名')
pwd = forms.CharField(min_length=6,label='密码')
r_pwd = forms.CharField(min_length=6,label='确认密码')
email = forms.EmailField(label='邮箱')
小结:
虽然这三种标签渲染的方式 第三种最为简介方便,但是局限性也最大,不能根据自己的需求调整标签,只能使用他提供的方法,如果常用的话还是选择第二种标签渲染方式。
将用户输入错误的信息在模板进行显示,用户提交后不会因为用户有错误信息而清空用户的输入内容,增加用户体验。
试图
def index(request):
if request.method == 'POST':
form = UserForm(request.POST)
if form.is\_valid():
print(form.cleaned\_data)
else:
print(form.cleaned\_data)
print(form.errors)
#这里将用户已经输入的值,重新传递给模板,用户输入过的内容不会刷新,增加用户体验。
return render(request,'index.html',locals())
form = UserForm()
return render(request,'index.html',locals())
模板
修改模板标签类型
class BooleanField(**kwargs):
默认的Widget:CheckboxInput
空值:False
规范化为:Python 的True 或 False。
如果字段带有required=True,验证值是否为True(例如复选框被勾上)。
错误信息的键:required
class CharField(**kwargs):
默认的Widget:TextInput
空值:''(一个空字符串)
规范化为:一个Unicode 对象。
如果提供,验证max_length 或min_length。 否则,所有的输入都是合法的。
错误信息的键:required, max_length, min_length
有两个参数用于验证:
max_length
min_length
如果提供,这两个参数将确保字符串的最大和最小长度。
charFied input()
class ChoiceField(**kwargs)¶
默认的Widget:Select
空值:''(一个空字符串)
规范化为:一个Unicode 对象。
验证给定的值在选项列表中存在。
错误信息的键:required, invalid_choice
invalid_choice 错误消息可能包含%(value)s,它将被选择的选项替换掉。
接收一个额外的必选参数:choices
用来作为该字段选项的一个二元组组成的可迭代对象(例如,列表或元组)或者一个可调用对象。
例如:
YEAR_IN_SCHOOL_CHOICES = (
('FR', 'Freshman'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
)
ChoiceField (select标签)
class DateField(**kwargs):
默认的Widget:DateInput
空值:None
规范化为:一个Python datetime.date 对象。
验证给出的值是一个datetime.date、datetime.datetime 或指定日期格式的字符串。
错误信息的键:required, invalid
接收一个可选的参数:
input_formats
一个格式的列表,用于转换一个字符串为datetime.date 对象。
DateField Dateinput 标签
class EmailField(**kwargs)
默认的Widget:EmailInput
空值:''(一个空字符串)
规范化为:一个Unicode 对象。
验证给出的值是一个合法的邮件地址,使用一个适度复杂的正则表达式。
错误信息的键:required, invalid
具有两个可选的参数用于验证,max_length 和min_length。如果提供,这两个参数确保字符串的最大和最小长度。
emailField EaillInput
class FileField(**kwargs)¶
默认的Widget:ClearableFileInput
空值:None
规范化为:一个UploadedFile 对象,它封装文件内容和文件名为一个单独的对象。
可以验证非空的文件数据已经绑定到表单。
错误信息的键:required, invalid, missing, empty, max_length
具有两个可选的参数用于验证,max_length 和 allow_empty_file。如果提供,这两个参数确保文件名的最大长度,而且即使文件内容为空时验证也会成功。
FileField
class ImageField(**kwargs)¶
默认的Widget:ClearableFileInput
空值:None
规范化为: An UploadedFile object that wraps the file content and file name into a single object.
验证文件数据已绑定到表单,并且该文件具有Pillow理解的图像格式。
错误信息的键:required, invalid, missing, empty, invalid_image
使用ImageField需要安装Pillow并支持您使用的图像格式。如果在上传图片时遇到损坏 图像错误,通常意味着Pillow不了解其格式。要解决这个问题,请安装相应的库并重新安装Pillow。
ImageField
class MultipleChoiceField(**kwargs)¶
默认的Widget:SelectMultiple
空值:[](一个空列表)
规范化为:一个Unicode 对象列表。
验证给定值列表中的每个值都存在于选择列表中。
错误信息的键:required, invalid_choice, invalid_list
invalid_choice错误消息可能包含%(value)s,将替换为所选择的选项。
对于ChoiceField,需要一个额外的必需参数choices。
MultipleChoiceField (select标签 multiple)
编辑模板标签属性
class CommentForm(forms.Form):
name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
url = forms.URLField()
comment = forms.CharField(widget=forms.TextInput(attrs={'size': '40'}))
编辑错误信息显示.
class RegForm(forms.Form):
username = forms.CharField(
min_length=3,
label="用户名",
help_text=‘‘,
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短8位"
}
)
password = forms.CharField(
min_length=3,
label="密码",
help\_text=‘6~16个字符,区分大小写‘,
error\_messages={
"required": "不能为空",
"invalid": "格式错误",
},
widget=forms.widgets.PasswordInput
)
re\_password = forms.CharField(
min\_length=3,
label="确认密码",
help\_text=‘请再次填写密码‘,
error\_messages={
"required": "不能为空",
"invalid": "格式错误",
},
widget=forms.widgets.PasswordInput)
gender = forms.fields.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性别",
initial=3,
widget=forms.widgets.RadioSelect
)
phone = forms.fields.CharField(
label="电话",
error\_messages={
"required": "不能为空",
},
)
email = forms.fields.CharField(
label=‘邮箱‘,
help\_text=‘6~18个字符,可使用字母、数字、下划线‘,
widget=forms.widgets.EmailInput,
error\_messages={
"required": "不能为空",
"invalid": "格式错误",
},
)
# 批量给form表单里的字段加样式
def \_\_init\_\_(self, \*args, \*\*kwargs):
super().\_\_init\_\_(\*args, \*\*kwargs)
for field in iter(self.fields):
field\_obj = self.fields\[field\]
if not isinstance(field\_obj, forms.fields.ChoiceField):
field\_obj.widget.attrs.update({‘class‘: ‘form-control‘})
# 全局钩子,此处用来判断两次输入的密码
def clean(self):
pwd = self.cleaned\_data.get(‘pwd‘)
re\_pwd = self.cleaned\_data.get(‘re\_pwd‘)
if pwd != re\_pwd:
self.add\_error(‘re\_pwd‘, ‘两次密码不一致‘)
raise ValidationError(‘两次密码不一致‘)
else:
return self.cleaned\_data
# 局部钩子函数,写给phone的校验函数
def clean\_phone(self):
phone = self.cleaned\_data.get(‘phone‘)
if not re.findall(‘^1\[0-9\]{10}$‘, phone):
raise ValidationError("格式错误!")
else:
return phone
我理解的钩子就是在 cleaned_data 中在进行逻辑处理,也就是说对通过form 校验的数值再次进行逻辑处理。
#局部钩子,钩子是在form规则对象正确的情况下才执行的程序
def clean\_name(self):
val = self.cleaned\_data.get('name')
print('val----------',val)#clean\_\[key\] 为固定写法
if not val.isdigit(): #如果正确直接返回改值 return val else: #否则返回错误信息 raise ValidationError('不能为纯数字')
视图
from django.shortcuts import render, HttpResponse
from django import forms
from django.forms import widgets
from django.forms import ValidationError
class UserForm(forms.Form):
name = forms.CharField(
min_length=4,
label='用户名',
error_messages={'required': '不能为空'})
pwd = forms.CharField(
min_length=4,
widget=widgets.PasswordInput
)
email = forms.EmailField(label='邮箱')
# 局部钩子,钩子是在form规则对象正确的情况下才执行的程序
def clean\_name(self): # clean\_\[key\] 为固定写法
val = self.cleaned\_data.get('name')
print('val----------', val)
if not val.isdigit():
return val
else:
raise ValidationError('不能为纯数字')
# 全局钩子,与局部钩子不同的是,对比多个已经校验过的数据。
def clean(self):
name = self.cleaned\_data.get('name')
pwd = self.cleaned\_data.get('pwd')
if name == pwd:
print('no')
raise ValidationError('用户名和密码不能一致')
else:
print('ok')
return self.cleaned\_data
def index(request):
if request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
print(form.cleaned_data)
else:
clean\_error = form.errors.get('\_\_all\_\_') # 获取所有错误信息
# 这里将用户已经输入的值,重新传递给模板,用户输入过的内容不会刷新,增加用户体验。
print(clean\_error, type(clean\_error))
return render(request, 'index.html', locals())
form = UserForm()
return render(request, 'index.html', locals())
模板
效果
手机扫一扫
移动阅读更方便
你可能感兴趣的文章