若是继承forms.Form的类中的每个字段,或者大部分字段都作了相同的约束,能够将该约束放到__init__中编写css
实例:每个字段都须要添加form-control类名html
1 class BookForm(forms.Form): 2 title = forms.CharField(max_length=32) 3 pub_date = forms.DateField() 4 price = forms.DecimalField(max_digits=8, decimal_places=2) 5 6 def __init__(self,*args,**kwargs): 7 super().__init__(*args,**kwargs) 8 for field in self.fields.values(): 9 field.widget.attrs.update({"class":"form-control"})
(1)choices做用:在数据库中用元组的第一项做为存储的值,在显示时,将元组的第二项做为显示的内容,便于前端使用下拉框前端
例:git
1 class Book(models.Model): 2 id=models.AutoField(primary_key=True) 3 title=models.CharField(max_length=32) 4 gender=models.IntegerField(choices=((1,"男"),(2,"女")),default=1)
(2)与get_gender_display()方法同时使用,用来获取元组第二项的内容数据库
(3)在forms组件中渲染时,只需将类型改变成ChoiceField()npm
例:django
1 class BookForm(forms.Form): 2 title = forms.CharField(label="书名",max_length=32) 3 pub_date = forms.DateField(label="出版社") 4 price = forms.DecimalField(label="价格",max_digits=8, decimal_places=2) 5 gender=forms.ChoiceField(choices=((1,"男"),(2,"女")))
(4) Choices的问题:小元组的内容是固定的,没法随着数据库的更改二更改,不灵活bootstrap
做用:帮助渲染前端页面的下拉框ide
优点:ModelChoiceField能够接收queryset属性的参数,内容能够随着数据库的更改而更改post
例:
1 class BookForm(forms.Form): 2 title = forms.CharField(label="书名",max_length=32) 3 gender=forms.ChoiceField(choices=((1,"男"),(2,"女"))) 4 publish=forms.ModelChoiceField(queryset=Publish.objects.all())
做用:帮助前端渲染页面的多选框,内容也能随着数据库的改变而改变
例:
1 class BookForm(forms.Form): 2 gender=forms.ChoiceField(choices=((1,"男"),(2,"女"))) 3 publish=forms.ModelChoiceField(queryset=Publish.objects.all()) 4 author=forms.ModelMultipleChoiceField(queryset=Author.objects.all())
正常状况下的model和form是没有关系的,全部forms组件必须咱们本身编写,可是ModelForm能够与model之间造成对应关系,这样就免去了咱们本身写model
(1)须要先引入forms组件的model类:from django.forms import ModelForm
(2)编写ModelForm类:
1 class BookModelForm(forms.ModelForm): 2 class Meta: 3 model=Book #与之关联的模型类 4 # fields="__all__" #能够渲染全部字段 5 fields=["title","price"] #能够渲染部分字段 6 7 exclide=[“title”] #能够渲染除某些字段外的全部字段
(3)为公共字段或大多数字段添加内容,批量处理(添加__init__方法)
Input标签的样式属性:
1 def __init__(self,*args,**kwargs): 2 super().__init__(*args,**kwargs) 3 for field in self.fields.values(): 4 field.widget.attrs.update({"class":"form-control"})
将错误转换成中文:
1 def __init__(self,*args,**kwargs): 2 super().__init__(*args,**kwargs) 3 for field in self.fields.values(): 4 field.error_messages={"required":"不能为空"}
(4)为单个字段添加内容(当每一个字段的内容不一样时)
1 Labels方法: 2 3 class BookModelForm(forms.ModelForm): 4 class Meta: 5 model=Book 6 fields="__all__" 7 labels={"title":"书籍名称","price":"价格"} 8 9 error_messages方法: 10 11 class BookModelForm(forms.ModelForm): 12 class Meta: 13 model=Book 14 fields="__all__" 15 error_messages={"title":{"required":"书籍名称不能为空"}} 16 17 widgets字段: 18 19 先引入:from django.forms import widgets as Fwidgets 20 21 class BookModelForm(forms.ModelForm): 22 class Meta: 23 model=Book 24 fields="__all__" 25 widgets = { 26 'pub_date': Fwidgets.Input(attrs={'type': 'date'}) 27 }
除了forms组件有的接口外,modelform还有save方法
Save方法会自动将干净的数据添加到表中,含有一对一,一对多,多对多的字段和表也会被处理好
(1)取到待编辑的model对象
例:book_obj=Book.objects.fillter(id=1).first()
(2)将model对象传入modelform
例:form=BookModelForm(request.POST,instance=book_obj)
获得的form就是待前端页面渲染的对象
结果:若是对ModelForm传了instance就至关于更新操做,没传instance,就至关于建立操做
做用:当某一段代码被重复利用的次数不少时,能够将其写到一个文件中,其余地方引用便可,减小代码的冗余性
例:在form.html中
1 <form action="" method="post" novalidate> 2 {% csrf_token %} 3 {% for field in form %} 4 <div class="form-group"> 5 <label for="title">{{ field.label }}</label> 6 {{ field }} 7 <span>{{ field.errors.0 }}</span> 8 </div> 9 {% endfor %} 10 <input type="submit" value="提交" class="btn btn-default pull-right"> 11 </form>
在增长书籍页面中:
1 <!DOCTYPE html> 2 <html lang="zh-CN"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> 8 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" 9 integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> 10 11 </head> 12 <body> 13 <h3>添加书籍</h3> 14 <div class="container"> 15 <div class="row"> 16 <div class="col-md-6 col-md-offset-3"> 17 {% include 'form.html' %} #表明将form.html中的代码放到这里 18 </div> 19 </div> 20 </div> 21 </body> 22 </html>
1 class Book(models.Model): 2 nid=models.AutoField(primary_key=True) 3 title=models.CharField(max_length=32) 4 price=models.DecimalField(max_digits=8,decimal_places=2) # 999999.99 5 pub_date=models.DateTimeField() # "2012-12-12" 6 publish=models.ForeignKey(to="Publish",on_delete=models.CASCADE) 7 authors=models.ManyToManyField(to="Author") 8 9 10 def __str__(self): 11 return self.title
1 from django.forms import widgets as Fwidgets 2 class BookModelForm(forms.ModelForm): 3 class Meta: 4 model=Book 5 fields="__all__" 6 labels={"title":"书籍名称","price":"价格"} 7 widgets = { 8 'pub_date': Fwidgets.Input(attrs={'type': 'date'}) 9 } 10 def __init__(self,*args,**kwargs): 11 super().__init__(*args,**kwargs) 12 for field in self.fields.values(): 13 field.widget.attrs.update({"class":"form-control"}) 14 field.error_messages={"required":"不能为空"} 15 16 等同于写了如下代码: 17 18 class BookForm(forms.Form): 19 20 21 title=forms.CharField(max_length=32) 22 price=forms.IntegerField() 23 pub_date=forms.DateField(widget=widgets.TextInput(attrs={"type":"date"})) 24 #publish=forms.ChoiceField(choices=[(1,"AAA"),(2,"BBB")]) 25 publish=forms.ModelChoiceField(queryset=Publish.objects.all()) 26 authors=forms.ModelMultipleChoiceField(queryset=Author.objects.all())
1 def add(request): 2 3 if GET请求: 4 5 form=BookModelForm() 6 7 return render(request,{“form”:form}) 8 9 else POST请求: 10 11 form=BookModelForm(request.POST) 12 13 if form.is_valid(): 14 15 form.save() 16 17 return render(“/”) 18 19 else: 20 21 return render(request,{“form”:form})
1 def edit(request,id): 2 3 edit_obj=Book.objects.get(pk=id) 4 5 if GET请求: 6 7 form=BookModelForm(instance=edit_obj) 8 9 return render(request,{“form”:form}) 10 11 else POST请求: 12 13 form=BookModelForm(request.POST,instance=edit_obj) 14 15 if form.is_valid(): 16 17 form.save() 18 19 return rediecr(“/”) 20 21 else: 22 23 return render(request,{“form”:form})
1 <form action="" method="post" novalidate> 2 3 4 {% csrf_token %} 5 {% for field in form %} 6 <div class="form-group"> 7 <label for="title">{{ field.label }}</label> 8 {{ field }} 9 <span>{{ field.errors.0 }}</span> 10 </div> 11 {% endfor %} 12 <input type="submit" value="提交" class="btn btn-default pull-right"> 13 14 15 </form>