在HTML種,表單是在<form>...</form>種的元素,它容許用戶輸入文本,選擇選項,操做對象等,而後發送這些數據到服務器html
表單元素容許用戶在表單種輸入內容如,文本域(textarea)、下拉列表、單選框(radio-buttons)、複選框(checkboxes)等。web
大多數狀況下被用到的表單標籤是輸入標籤(<input>),輸入類型是由類型屬性(type)定義的,大多數常常被用到的輸入類型下面作簡單介紹:數據庫
(1)文本域(Text Fields)django
文本域經過<input type="text">標籤來設定,當用戶要在表單種輸入字母,數字等內容是,就會用到文本域,在大多數瀏覽器種,文本域的缺省寬度是20個字符:瀏覽器
<form> 姓名:<input type="text" name="username"><br> </form>
(2)密碼字段服務器
密碼字段經過標籤<input type="password">來定義,密碼字段字符不會明文顯示,而是以星號或圓點替代:app
<form> 姓名:<input type="text" name="username"><br> 密碼:<input type="password" name="password"> </form>
(3)單選按鈕(Radio Buttons)函數
<input type="radio">標籤訂義了表單單選框選項post
<form> 姓名:<input type="text" name="username"><br> 密碼:<input type="password" name="password"><br> 性別:<input type="radio" name="sex" value="man">男<input type="radio" name="sex" value="weman">女<br> </form>
(4)複選框(Checkboxes)學習
<input type="checkbox"定義了複選框,用戶能夠從若干個給定的選擇種選擇多個
<form> 姓名:<input type="text" name="username"><br> 密碼:<input type="password" name="password"><br> 性別:<input type="radio" name="sex" value="man">男<input type="radio" name="sex" value="weman">女<br> 愛好:<input type="checkbox" name="vehicle" value="yundong">運動 <input type="checkbox" name="vehicle" value="youxi">遊戲 <input type="checkbox" name="vehicle" value="xuexi">學習 </form>
(5)提交按鈕(Submit Button)
<input type="submit">定義了提交按鈕,當用戶單擊確認按鈕時,表單的內容就會被傳送到動做屬性定義的目的文件中
<form action="index.html" method="post"> 姓名:<input type="text" name="username"><br> 密碼:<input type="password" name="password"><br> 性別:<input type="radio" name="sex" value="man">男<input type="radio" name="sex" value="weman">女<br> 愛好:<input type="checkbox" name="vehicle" value="yundong">運動 <input type="checkbox" name="vehicle" value="youxi">遊戲 <input type="checkbox" name="vehicle" value="xuexi">學習<br> <input type="submit" value="提交"> </form>
瀏覽器表單中的數據會發往action屬性指定的URL,而且使用它的method屬性指定的HTTP方法post,當點擊submit類型的提交時,會將數據發送到index.html中。
HTML5有許多新的input類型:
color類型選取顏色,date類型日期選擇器,datetime-local類型選擇一個日期和時間,email類型用於e-mail地址的輸入域,month類型容許選擇一個月份,number類型用於數值的輸入域,rang類型定義必定範圍內數字的輸入域,顯示爲滑動條可設置最大值max和最小值min,search類型用於搜索域,tel類型定義電話號碼字段,time類型定義一個時間選擇,url類型用於URL地址的輸入域,week類型容許選擇周和年。
處理表單時只會用到GET和POST兩種HTTP方法,GET方法會將提交的數據捆綁到URL中,而POST經過加密的方式在後臺提交
Django會處理涉及表單的三個部分:
準備並重組數據,以便下一步的渲染;爲數據建立HTML表單;接收並處理客戶端提交的表單以及數據。
Django表單系統的核心組件是Form類,Form類描述一張表單並決定它如何工做並呈現
Form類,相似於模型類的字段映射到數據庫字段的方式,表單類的字段會映射到HTML表單的<input>元素,表單字段自己也是類,它們管理表單數據並提交表單執行驗證,在瀏覽器中表單字段以HTML控件的形式展示給咱們,在Django中每一個字段類型都有與之匹配的控件類,在必要時也能夠覆蓋
在Django中渲染一個對象的過程一般爲:在視圖中獲取數據,而後將數據傳遞給模板,使用模板變量將數據擴展到HTML標記,下面咱們在Django中構建表單
在app中新建forms.py文件:
from django import forms #首先它繼承Form類,而後經過控件類CharField定義文本域並指定屬性 class IndexForm(forms.Form): username = forms.CharField(label='姓名',max_length=100)
而後在編輯視圖並引入表單類:
#views.py from django.shortcuts import render from django.http import HttpResponse from .forms import IndexForm #新建視圖函數處理表單,首先判斷提交類型爲post則經過表單類接收POST請求數據並填充表單類,而後判斷數據是否有效並提交到後臺,此處作演示只作判斷並提示接收成功,
#若是提交類型不爲POST則建立空表單經過變量傳遞給模板 def get_name(request): if request.method == 'POST': form = IndexForm(request.POST) print(form) if form.is_valid(): return HttpResponse('提交到後臺成功!') else: form = IndexForm() return render(request,'index.html',{'form':form})
表單類生成的數據以下:
<tr><th><label for="id_username">姓名:</label></th><td><input type="text" name="username" value="root" maxlength="100" required id="id_username"></td></tr>
在模板中只需簡單的配置form標籤並接收變量,注意表單不包含提交標籤須要在模板中本身建立
<form action="{% url 'formtest' %}" method="post"> {% csrf_token %} #此處爲跨站請求僞造保護功能django自提供 {{ form }} <input type="submit" value="提交"> </form>
頁面程序效果:
<form action="/" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="e9Je91NyzZFWx83yXQbSiHYYjH3g4tsiz22zAjEAhSfKnNzPjAINCVd1iHZAnC4B"> <label for="id_username">姓名:</label><input type="text" name="username" maxlength="100" required="" id="id_username"> <input type="submit" value="提交"> </form>
在模板中咱們只需將表單在上下問中進行渲染,來獲得對應的標籤元素,如上面的form變量渲染{{ form }}
但在表單渲染選項還可使用其餘渲染方式:
{{ form.as_table }}包裝在<tr>標記中的表格單元格顯示數據,但必須本身提供外層<table>元素
{{ form.as_p }}包裹在<p>標記中的顯示數據
{{ form.as_ul }}包裹在<li>標記中顯示數據,但必須本身提供外層<ul>元素
手動渲染字段:
循環遍歷每一個字段對字段屬性手動渲染,以下field.errors輸出包含改字段驗證的錯誤信息,field.label_tag爲帶<label>標籤的label值
#遍歷表單字段 <form action="{% url 'index' %}" method="post"> {% csrf_token %} {% for field in form %} {{ field.errors }} {{ field.label_tag }} {{ field }}<br> {% endfor %} <input type="submit" value="提交"> </form> #渲染效果 <form action="/" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="benu1PCIYH6XKtSxa7cQyR8wwwIYvae7w7GPs7tKGAGLA8oOwRJLS5nzvwEiOjQq"> <label for="id_subject">Subject:</label> <input type="text" name="subject" maxlength="100" required="" id="id_subject"><br> <label for="id_message">Message:</label> <textarea name="message" cols="40" rows="10" required="" id="id_message"></textarea><br> <label for="id_sender">Sender:</label> <input type="email" name="sender" required="" id="id_sender"><br> <label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself"><br> <input type="submit" value="提交"> </form>
field.label_tag:輸出field的label元素,如:<label for="id_subject">Subject:</label>
field:輸出field的input,如:<input type="text" name="subject" maxlength="100" required="" id="id_subject">
field.errors:輸出field的errors元素,通常在form表單驗證出錯時顯示
field.id_for_label:輸出字段的ID值
field.value:輸出字段填充的值
field.html_name:輸出字段的名稱
field.help_text:輸出與該字段的幫助文本
field.is_hidden:若是是隱藏字段屬性值爲True不然爲False
Formset表單集是多個表單的集合,Formset在web開發中應用很廣泛,它可讓用戶在同一個頁面提交多張表單,一鍵添加多個數據
Django針對不一樣的formset提供了三種方法:formet_factory,modelformset_factory和inlineformset_factory
(1)使用formset_factory
對應繼承forms.Form的自定義表單,咱們可使用formset_factory,經過設置extra指定表單數量,max_num指定表單數量最大值
首先建立表單並使用formset_factory方法指定建立表單集並指定表單數量
#forms.py from django import forms from django.forms import formset_factory class registerForm(forms.Form): username = forms.CharField(max_length=120) age = forms.IntegerField() pub_date = forms.DateField(required=False) registerFormset = formset_factory(registerForm,extra=3,max_num=5)
在視圖views.py裏使用formset
#views.py from django.shortcuts import render,HttpResponse from .forms import registerFormset def register(request): if request.method == 'POST': formset = registerFormset(request.POST,request.FILES) if formset.is_valid(): return HttpResponse('formset is ok') else: formset = registerFormset() return render(request,'register.html',context={'formset':formset})
最後在模版中應用表單便可
<form action="{% url 'register' %}" method="post"> {{ formset.management_form }} {% for form in formset %} {{ form.as_p }} {% endfor %} </form>
首先建立model模型:
from django.db import models from django.utils import timezone TITLE_CHOICES = ( ('MR','Mr.'), ('MRS','Mrs.'), ('MS','Ms.'), ) class Author(models.Model): name = models.CharField(max_length=100,verbose_name='姓名') title = models.CharField(max_length=3,choices=TITLE_CHOICES,verbose_name='標題') birth_date = models.DateField(default=timezone.now,blank=True,null=True,verbose_name="建立時間") def __str__(self): return self.name
根據模型建立表單文件:
#forms.py #導入模型表單類 from django.forms import ModelForm from .models import Author #繼承模型表單類建立表單 class AuthorForm(ModelForm): class Meta: model = Author #指定model fields = ['name','title','birth_date'] #指定要顯示的字段,全顯示可以使用"__all__"
在經過模型建立表單時,咱們只需繼承Django的模型表單類,而後重寫它的屬性便可,model指定要建立表單的模型,fields指定顯示的模型字段,全顯示能夠用「__all__"代替,還有其餘的類屬性exclude指定排除的字段,labels指定提示信息,help_texts指定幫助提示信息,widgets指定自定義插件,error_messages自定義錯誤信息,field_classes自定義字段類,localized_fields本地化時區時間,根據setting中TIME_ZONE設置的不一樣時區顯示時間
from django import forms from django.forms import ModelForm from .models import Author class AuthorForm(ModelForm): class Meta: model = Author fields = ['name','title','birth_date'] widgets = { 'title':forms.Textarea(attrs={'cols':80,'rows':20}) } #覆蓋重寫title字段的類型 labels = { 'name':'做者', 'title':'頭銜', 'birth_date':'出生日期', } error_messages = { 'name':{ 'max_length':'名字長度在15個字符內', } }
在django中的模型字段和表單字段的字段類型定義都差很少,比較特殊的是ForeignKey和ManyToManyField模型字段在表單中的字段類型會有所不一樣:
ForeignKey由django.forms.ModelChoiceField表示,它是一個ChoiceField,其選項是一個模型QuerySet
ManyToManyField由django.forms.ModelMultipleChoiceField表示,它是一個MultipleChoiceField,其選項爲一個模型QuerySet
另外,每一個生成的表單字段的屬性設置以下:
若是模型字段設置了blank=True,那麼表單字段的required屬性被設置爲False,否知爲True
表單字段的label設置爲模型字段的verbose_name,而且首字母大寫
表單字段的help_text設置爲模型字段的help_text
若是模型字段設置了choices,那麼表單字段的widget會被設置爲select,其選項來自模型字段的choices,這些選項一般包含一個默認選中的空選項,若是字段設置了必填,則會強制用戶進行選項,若是模型字段設置了blank=False以及一個明確的default值,則表單字段中不會包含空選項
在視圖中使用表單:
#views.py from django.shortcuts import render,HttpResponse from .forms import AuthorForm from .models import Author def test(request): if request.method == 'POST': author_form = AuthorForm(request.POST) if author_form.is_valid(): author_form.save(commit=True) return HttpResponse('提交成功') else: author_form = AuthorForm() obj = Author.objects.all() return render(request,'test.html',{"author_form":author_form,'obj':obj})
views.py中使用ModelForm的save()方法將表單數據保存到數據庫中,參數commit爲True時寫如數據庫,若是爲False則建立一個Model對象但不保存到數據庫中,若是要更新某個對象可使用save的instance參數來指定要更新的model對象
在模板中提交併展現數據:
#test.html <body> <h2>Author Form:</h2> <form action="{% url 'test' %}" method="post"> {% csrf_token %} {{ author_form }} <input type="submit" value="提交"> </form> <h2>Author Form output:</h2> <ul> {% for i in obj %} <li>{{ i.id }}:{{ i.name }}:{{ i.title }}:{{ i.birth_date }}</li> {% endfor %} </ul> </body>
表單模板ModelForm中有一個工廠函數能夠直接經過Model建立表單modelform_factory(),在不須要不少自定義的狀況下是很方便的
from .models import Author from django import forms from django.forms.models import modelformset_factory modelform_Author = modelformset_factory(model=Author,fields=('__all__'),widgets={'title':forms.Textarea()})