概述:
ModelForm类是form是组件中Form的一个子类,所以,也是处理表单的,但功能要比Form类强大,而且使用方便。
步骤:
1、自定义一个类,继承ModelForm
1 from django import forms 2 3 class BookModelForm(forms.ModelForm): 4 5 class Meta: 6 model = models.Book #选定一个表对应的模型类 7 fields = ['title','price'] #要进行数据校验的字段 8 fields = "__all__" #校验所有的字段 9 exclude =['pub_date'] #排除校验的字段 10 #自定义钩子 11 def clean_title(self): 12 val = self.cleaned_date.get('title') 13 if not val.isdigit(): 14 return val 15 else: 16 raise ValidationError("书名不能是纯数字") 17
2、使用ModelForm校验数据
1 def addbook(request): 2 if request.method=="POST": 3 4 form=BookModelForm(request.POST) 5 if form.is_valid(): #判断校验是否通过 6 form.save() #保存数据 7 return redirect("/books/") 8 else: 9 return render(request, 'addbook.html', locals()) #带着出错的数据传给addbook.html,显示错误信息 10 11 else: 12 form=BookModelForm() # modelforms组件 13 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组件中的运用:
1 class BookModelForm(forms.ModelForm): 2 class Meta: 3 model=models.Book #指定book表对应的模型类 4 fields="__all__" #校验所有字段 5 #定制字段的标签 6 labels={ 7 'publish':'出版社', 8 'authors':"作者" 9 } 10 #定制字段的对应的错误信息 required是错误名 11 error_messages={ 12 "title":{"required":'该字段不能为空'} 13 } 14 #定制字段生成的标签的属性 15 widgets={ 16 'title':wid.TextInput(attrs={'class':'form-control'}), 17 'price':wid.NumberInput(attrs={'class':'form-control'}), 18 'pub_date':wid.DateInput(attrs={'class':'form-control ','type':'date'}), 19 'publish':wid.Select(attrs={'class':'form-control'}), 20 'authors':wid.SelectMultiple(attrs={'class':'form-control'}) 21 } 22 #自定义钩子 显示不同的错误信息 23 def clean_title(self): 24 val = self.cleaned_data.get("title") 25 if not val.isdigit(): 26 return val 27 else: 28 raise ValidationError("书名不能是纯数字")
1 def change_view(self,request,id): 2 3 change_obj = self.model.objects.filter(pk=id).first() 4 #获取到自己的定义的ModelForm类的类名 5 DetialModelForm = self.get_model_form_class() 6 7 if request.method=='GET': 8 form = DetialModelForm(instance=change_obj) 9 return render(request,'stark/change_view.html',{"form":form}) 10 11 else: 12 form = DetialModelForm(request.POST,instance=change_obj) 13 if form.is_valid(): 14 #校验通过,保存数据 15 form.save() 16 return redirect(self.get_list_url()) 17 else: 18 return render(request, 'stark/change_view.html', {"form": form}) 19