概述:
ModelForm类是form是组件中Form的一个子类,所以,也是处理表单的,但功能要比Form类强大,而且使用方便。
步骤:
1、自定义一个类,继承ModelForm
from django import forms class BookModelForm(forms.ModelForm): class Meta:
model = models.Book #选定一个表对应的模型类
fields = ['title','price'] #要进行数据校验的字段
fields = "__all__" #校验所有的字段
exclude =['pub_date'] #排除校验的字段
#自定义钩子
def clean_title(self):
val = self.cleaned_date.get('title')
if not val.isdigit():
return val
else:
raise ValidationError("书名不能是纯数字")
2、使用ModelForm校验数据
def addbook(request):
if request.method=="POST": form=BookModelForm(request.POST)
if form.is_valid(): #判断校验是否通过
form.save() #保存数据
return redirect("/books/")
else:
return render(request, 'addbook.html', locals()) #带着出错的数据传给addbook.html,显示错误信息 else:
form=BookModelForm() # modelforms组件
return render(request,'addbook.html',locals())
数据校验
知识补充:
choices的用法:
1/ 在模型类中 比如员工表:
gender = models.IntegerField(choices=((1, '男‘ ) , (2 , '女' )))
alex是模型类的一个对象
alex.gender ----> 1
alex.get_gender_display() ------>男
2/ 在form类中(会自动渲染成select标签)
state= forms.ChoiceField(choices = ((1, '已出版' ), (2, '未出版' )))
一对多关系字段:
publish = forms.ChoiceField(choices = (list(models.publish.objects.all().value_list('pk', 'name' ))))
或 publish = forms.ModelChoiceField( queryset=models.Publish.objects.all() )
多对多关系字段:
authors = forms,ModelMultipleChoiceField(queryset = models.Author.objects.all())
widgets用法
form django import forms from django.forms import widgets class EmpForm(forms.Form):
name=forms.CharField(min_length=5,
label="姓名",
error_messages={"required":"该字段不能为空!"},
widget=widgets.TextInput(attrs={"class":"form-control","id":"yuan"})
)
age=forms.IntegerField(label="年龄",
widget=widgets.PasswordInput(attrs={"class": "form-control", "id": "yuan"})
)
salary=forms.CharField(label="薪水") def clean_name(self):
val=self.cleaned_data.get("name")
# 二次校验
if val.isdigit():
raise ValidationError("姓名不能是纯数字!")
elif Emp.objects.filter(name=val):
raise ValidationError("该员工已存在!")
else:
return val
综合使用,在satrk组件中的运用:
class BookModelForm(forms.ModelForm):
class Meta:
model=models.Book #指定book表对应的模型类
fields="__all__" #校验所有字段
#定制字段的标签
labels={
'publish':'出版社',
'authors':"作者"
}
#定制字段的对应的错误信息 required是错误名
error_messages={
"title":{"required":'该字段不能为空'}
}
#定制字段生成的标签的属性
widgets={
'title':wid.TextInput(attrs={'class':'form-control'}),
'price':wid.NumberInput(attrs={'class':'form-control'}),
'pub_date':wid.DateInput(attrs={'class':'form-control ','type':'date'}),
'publish':wid.Select(attrs={'class':'form-control'}),
'authors':wid.SelectMultiple(attrs={'class':'form-control'})
}
#自定义钩子 显示不同的错误信息
def clean_title(self):
val = self.cleaned_data.get("title")
if not val.isdigit():
return val
else:
raise ValidationError("书名不能是纯数字")
示例
def change_view(self,request,id): change_obj = self.model.objects.filter(pk=id).first()
#获取到自己的定义的ModelForm类的类名
DetialModelForm = self.get_model_form_class() if request.method=='GET':
form = DetialModelForm(instance=change_obj)
return render(request,'stark/change_view.html',{"form":form}) else:
form = DetialModelForm(request.POST,instance=change_obj)
if form.is_valid():
#校验通过,保存数据
form.save()
return redirect(self.get_list_url())
else:
return render(request, 'stark/change_view.html', {"form": form})
示例 sites.py