若是繼承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>