django表单
1.表单绑定状态
Django为继承自Form类的表单维护了一个绑定(bound)状态
- 如果一个表单对象在实例化候被赋予过数据内容,则称该表单处于bound状态。只有处于bound状态的表单才具有表单数据验证(validate data)的功能
- 如果未被赋予过数据内容,则表单处于unbound状态。只有处于unbound状态的表单才能被赋予数据,使表单变为bound状态。
注意:已经处于bound状态的表单不能在python代码中修改其中的数据,而只能有网页用户在页面中输入数据进行修改
可以通过Form的is_bound属性检查表单状态
f = MomentForm()
print(f.is_bound)
f = MomentForm({"headline":"hello"})
print(f.is_bound())
2 表单数据验证
Django表单数据验证是指在服务器端用Python代码验证表单中数据的合法性。表单验证费为如下两类:
- 字段属性验证:验证表单中字段是否符合特定的格式要求,比如CharField 字段是否满足了max_length要求 非空字段是否已赋值
- 自定义逻辑验证:验证开发中自定义的一些逻辑要求,比如moment的content长度必须比headline长不能包含某些关键字等
1.字段属性验证
字段属性验证要求通过model中字段的约束完成,在form渲染的过程中django会自动根据验证约束要求验证字段内容,如果字段不符合呀求,则会自动显示错误信息并提示用户。比如对于在前端页面中不输入 如果设置表单对应model的content字段不能为空,则用户不输入content内容并提交表单后,该页面渲染结果会要求输出类似“this
field is required”
除此之外 开发者也可以用is_valid()函数在代码中获得表单验证是否通过信息 用errors属性获得错误提示信息
f = MomentForm({'user_name':'david'})
print(f.is_valid())
False
print(f.error)
{'content':['This field is required']}
由于在MomentForm的初始化中只设置了user_name 的值,而没有设置不能为空的content的值 因此此时调用表单的is_valid()结果为False。表单is_valid()函数通常在视图函数的开发中起到重要作用。下面是表单视图函数的设计结构
def viewer(request):
if request.method=='POST':
form = XXXForm(request.POST)
if form.is_valid():
#此处编写正常的表单提交的业务逻辑
#处理完成后用redirect重定向到页面
else:
#此处编写提交数据不完全的业务逻辑,比如现实特定的错误信息等
2.自定义逻辑验证
如果开发者需要在django进行表数据验证时判断自定义的复杂逻辑,则可以通过重载Form子类的clean函数进行定义。修改MomentForm的定义如下
from django.forms import ModelForm,ValidationError
from app.models import Moment
class MomentForm(ModelForm):
class Meta:
model = Moment
fields = "__all__"
def clean(self):
cleaned_data = super(MomentForm,self).clean()
content = cleaned_data.get("content")
if content is None:
raise ValidationError("请输入content内容")
elif contend.find("ABCD")>=0:
raise ValidationError("不能输入敏感字ABCD!")
return cleaned_data
"""
在MomentForm中增加了对clean函数的定义,该函数在开发者调用Form.is_valid()函数时自动被django调用,开发者应该奖针对表单的自定义逻辑验证逻辑卸载clean()函数中,如果验证检测到逻辑错误,则通过抛出validationError()异常结束本次验证,如果验证数据正确 则返回从基类中得到的cleaned-data自定义表单数据验证结果
"""
3.检查变更字段
当视图函数收到表单提交的POST的时候,经常需要ton过验证用户是否修改了表单数据然后进行相应的处理,Django提供了表单函数 has_changed()来判断用户是否修改过表单数据,使用方法如下
def view_moment(request):
data = {"content":"please input the content","user_name":"匿名",'kind':'python技术'}
f = MomentForm(request.POST,initial=data)
if f.has_changed():
#在此处编写保存f的代码
"""
注意:Form实例初始化需要传入两个参数
+ request.POST :django从其中解析出用户的输入数据
initial:Form的初始值 在调用has_changed时 django用initial中的指端与初始值比较,如果有变化则返回True
"""
django不仅仅能够判断是否有字段修改过,还能用changed_data属性精确定位用户对那些字段进行了修改。changed_data是包含字段名的列表
if f.has_changed():
print("如下字段进行了修改")
for field in f.changed_data:
print(field)