Django基礎(5): 表單forms的設計與使用
Django網路應用開發的5項基礎核心技術包括,,,和Form(表單)的使用。今天小編我就來拼個老命給你來介紹下第五項Django核心基礎知識之表單forms的設計與使用吧, 並重點介紹下表單的驗證。想持續瞭解後續Django Web開發技術請訂閱我的公眾號【Python與Django大咖之路】。
什麼是表單?何時使用表單?
在web開發裡表單的使用必不可少。表單用於讓使用者提交資料或上傳檔案,表單也用於讓使用者編輯已有資料。Django的表單Forms類的作用是把使用者輸入的資料轉化成Python物件格式,便於後續操作(比如儲存,修改)。
自定義表單
類似模型,Django表單也由各種欄位組成。表單可以自定義,也可以由模型Models建立。值得注意的是模型裡用的是verbose_name來描述一個欄位, 而表單用的是label。
下面是兩個ContactForm的例子。一個自定義,一個從Model建立。
from django import forms
from .models import Contact
class ContactForm1(forms.Form):
name = forms.CharField(label="Your Name", max_length=255)
email = forms.EmailField(label="Email address")
class ContactForm2(forms.ModelForm):
class Meta:
model = Contact
fields = ('name' , 'email',)
Django的常用做法是在app資料夾下建立一個forms.py,專門存放app中所定義的各種表單,這樣方便集中管理表單。如果要使用上述表單,我們可以在檢視views.py裡把它們像模型一樣import進來直接使用。
表單例項化
下面方法可以例項化一個空表單,但裡面沒有任何資料,可以通過 {{ form }}在模板中渲染。
form = ContactForm()
使用者提交的資料可以通過以下方法與表單結合,生成與資料結合過的表單(Bound forms)。Django只能對Bound forms進行驗證。
form = ContactForm(data=request.POST, files= request.FILES)
模板檔案中使用form
模板檔案中我們可以通過{{ form.as_p }}, {{ form.as_li }} 和 {{ form.as_table }}中渲染表單。如果你想詳細控制每個field的格式,你可以採取以下方式。
{% block content %}
<div class="form-wrapper">
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
<div class="button-wrapper submit">
<input type="submit" value="Submit" />
</div>
</form>
</div>
{% endblock %}
表單實際使用案例
我們現在需要設計一個表單讓使用者完成註冊。我們先在app目錄下新建forms.py, 然後建立一個RegistrationForm。程式碼如下:
from django import forms
from django.contrib.auth.models import User
class RegistrationForm(forms.Form):
username = forms.CharField(label='Username', max_length=50)
email = forms.EmailField(label='Email',)
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password Confirmation', widget=forms.PasswordInput)
當然你也可以不用新建forms.py而直接在html模板裡寫表單,但我並不建議這麼做。用forms.py的好處顯而易見:
所有的表單在一個檔案裡,非常便於後期維護,比如增添或修訂欄位。
forms.py可通過clean方法自定義表單驗證,非常便捷(見後文)。
我們使用RegistrationForm的檢視views.py是這樣子的。
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.models import User
from .forms import RegistrationForm
from django.http import HttpResponseRedirect
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password2']
# 使用內建User自帶create_user方法建立使用者,不需要使用save()
user = User.objects.create_user(username=username, password=password, email=email)
# 如果直接使用objects.create()方法後不需要使用save()
return HttpResponseRedirect("/accounts/login/")
else:
form = RegistrationForm()
return render(request, 'users/registration.html', {'form': form})
模板是registration.html這樣子的。如果你需要通過表單上傳圖片或檔案,一定不要忘了給form加enctype="multipart/form-data"屬性。
<form action=”.” method=”POST”>
{{ form.as_p }}
</form>
我們來看下RegistrationForm是怎麼工作的:
當用戶通過POST方法提交表單,我們將提交的資料與RegistrationForm結合,然後驗證表單RegistrationForm的資料是否有效。
如果表單資料有效,我們先用Django User模型自帶的create_user方法建立user物件,再建立user_profile。使用者通過一張表單提交資料,我們實際上分別儲存在兩張表裡。
如果使用者註冊成功,我們通過HttpResponseRedirect方法轉到登陸頁面
如果使用者沒有提交表單或不是通過POST方法提交表單,我們轉到註冊頁面,生成一張空的RegistrationForm
表單的驗證
每個forms類可以通過clean方法自定義表單驗證。如果你只想對某些欄位進行驗證,你可以通過clean_欄位名方式自定義表單驗證。如果使用者提交的資料未通過驗證,會返回ValidationError,並呈現給使用者。如果使用者提交的資料有效form.is_valid(),則會將資料儲存在cleaned_data裡。
在上述使用者註冊的案例裡,我們在RegistrationForm通過clean方法添加了使用者名稱驗證,郵箱格式驗證和密碼驗證。程式碼如下。
from django import forms
from django.contrib.auth.models import User
import re
def email_check(email):
pattern = re.compile(r"\"?([-a-zA-Z0-9.`?{}][email protected]\w+\.\w+)\"?")
return re.match(pattern, email)
class RegistrationForm(forms.Form):
username = forms.CharField(label='Username', max_length=50)
email = forms.EmailField(label='Email',)
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password Confirmation', widget=forms.PasswordInput)
# Use clean methods to define custom validation rules
def clean_username(self):
username = self.cleaned_data.get('username')
if len(username) < 6:
raise forms.ValidationError("Your username must be at least 6 characters long.")
elif len(username) > 50:
raise forms.ValidationError("Your username is too long.")
else:
filter_result = User.objects.filter(username__exact=username)
if len(filter_result) > 0:
raise forms.ValidationError("Your username already exists.")
return username
def clean_email(self):
email = self.cleaned_data.get('email')
if email_check(email):
filter_result = User.objects.filter(email__exact=email)
if len(filter_result) > 0:
raise forms.ValidationError("Your email already exists.")
else:
raise forms.ValidationError("Please enter a valid email.")
return email
def clean_password1(self):
password1 = self.cleaned_data.get('password1')
if len(password1) < 6:
raise forms.ValidationError("Your password is too short.")
elif len(password1) > 20:
raise forms.ValidationError("Your password is too long.")
return password1
def clean_password2(self):
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Password mismatch. Please enter again.")
return password2
通用視圖裡使用表單
在Django基於類的檢視(Class Based View)裡使用表單也非常容易,只需定義form_class就好了。下面是一個建立一篇新文章的例子。
from django.views.generic.edit import CreateView
from .models import Article
from .forms import ArticleForm
class ArticleCreateView(CreateView):
model = Article
form_class = ArticleForm
template_name = 'blog/article_create_form.html'
自定義表單輸入的widget
Django forms的每個欄位你都可以選擇你喜歡的輸入widget,比如多選,複選框。你還可以定義每個widget的css屬性。如果你不指定,Django會使用預設的widget,有時比較醜。
比如下面這段程式碼定義了表單姓名欄位的輸入控制元件為Textarea,還指定了其樣式css。
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(
max_length=255,
widget=forms.Textarea(
attrs={'class': 'custom'},
),
)
設定widget可以是你的表單大大美化,方便使用者選擇輸入。比如下面案例裡對年份使用了SelectDateWidget,對課程使用RadioSelect, 顏色則使用了複選框CheckboxSelectMultiple。
from django import forms
BIRTH_YEAR_CHOICES = ('1980', '1981', '1982')
COLORS_CHOICES = (
('blue', 'Blue'),
('green', 'Green'),
('black', 'Black'),
)
class SimpleForm(forms.Form):
birth_year = forms.DateField(widget=forms.SelectDateWidget(years=list(BIRTH_YEAR_CHOICES)))
favorite_colors = forms.MultipleChoiceField(
required=False,
widget=forms.CheckboxSelectMultiple,
choices=list(COLORS_CHOICES),
)
表單資料初始化
有時我們需要對錶單設定一些初始資料,我們可以通過initial方法,如下所示。
form = ContactForm(
initial={
'name': 'First and Last Name',
},)
其編輯修改類應用場景中,我們還要給表單提供現有物件的資料,而不是渲染一張空表單,這時我們可這麼做。該方法僅適用於由模型建立的ModelForm,而不適用於自定義的表單。
contact = Contact.objects.get(id=1)
form = ContactForm(instance = contact)
對於自定義的表單,可以設定default_data。
default_data = {'name': 'John', 'email': '[email protected]', }
form = ContactForm(default_data)
Formset的使用
有的時候使用者需要在1個頁面上使用多個表單,比如一次性提交新增多本書的資訊,這時我們可以使用formset。這是一個表單的集合。
建立一個FormSet我們可以這麼做:
from django import forms
class BookForm(forms.Form):
name = forms.CharField(max_length=100)
title = forms.CharField()
pub_date = forms.DateField(required=False)
# forms.py - build a formset of books
from django.forms import formset_factory
from .forms import BookForm
# extra: 額外的空表單數量
# max_num: 包含表單數量(不含空表單)
BookFormSet = formset_factory(BookForm, extra=2, max_num=1)
在檢視檔案views.py裡,我們可以像使用form一樣使用formset。
# views.py - formsets example.
from .forms import BookFormSet
from django.shortcuts import render
def manage_books(request):
if request.method == 'POST':
formset = BookFormSet(request.POST, request.FILES)
if formset.is_valid():
# do something with the formset.cleaned_data
pass
else:
formset = BookFormSet()
return render(request, 'manage_books.html', {'formset': formset})
模板裡可以這樣使用formset。
<form action=”.” method=”POST”>
{{ formset }}
</form>
後續我們會專門介紹formset的使用案例。欲知更多Python Web開發與Django實戰案例,請關注我們的微信公眾號【Python與Django大咖之路】。
相關推薦
Django基礎(5): 表單forms的設計與使用
Django網路應用開發的5項基礎核心技術包括,,,和Form(表單)的使用。今天小編我就來拼個老命給你來介紹下第五項Django核心基礎知識之表單forms的設計與使用吧, 並重點介紹下表單的驗證。想
Django中的表單(forms.Form)
Django中的表單: 1、HTML中的表單:用來提交資料給伺服器的,不管後臺的伺服器用的是Django還是PHP語言還是其他語言 2、Django中的表單: ①渲染表單模板 ②表單驗證資料是否合法 3、Django中表單使用流程: ①app下新建fo
Django基礎(11): 表單集合Formset的高階用法詳解
Formset(表單集)是多個表單的集合。Formset在Web開發中應用很普遍,它可以讓使用者在同一個頁面上提交多張表單,一鍵新增多個數據,比如一個頁面上新增多個使用者資訊。今天小編我就介紹下Django Formset的基礎知識,Formset的分類以及如何使用Forms
JavaScript基礎 submit按鈕配合form的onsubmit實現表單的提交與驗證
java asc body bmi 是我 技術 pos true value 鎮場詩: 清心感悟智慧語,不著世間名與利。學水處下納百川,舍盡貢高我慢意。 學有小成返哺根,願鑄一良心博客。誠心於此寫經驗,願見文者得啟發。—————————————————————
JavaScript基礎 submit按鈕結合onclick事件 實現表單的提交與驗證
ret vs2015 基礎 result oct 學習資源 charset 簡單 添加 鎮場詩: 清心感悟智慧語,不著世間名與利。學水處下納百川,舍盡貢高我慢意。 學有小成返哺根,願鑄一良心博客。誠心於此寫經驗,願見文者得啟發。————————————————
html表單標簽與表單設計
多行文本 表單 off inpu 域名 type cti blog 允許 1<form>標記及其屬性 表單使用<form>和</form>來定義的,<form>標記有屬性:name、method、action、target等屬
Django從models建立表單(forms)
https://docs.djangoproject.com/en/1.8/topics/forms/modelforms/ = ModelForm 對於對映到model的表單,避免重複定義屬性,Django提供了一個幫助函式讓你從一個Model直接建立Form. from
AngulairJS表單輸入驗證與mvc
oot 表單 名稱 操作 數據庫 root min 位置 input AngulairJS表單輸入驗證 1.表單中,常用的驗證操作有:$dirty 表單有填寫記錄、$valid 字段內容合法的、$invalid 字段內容是非法的、$pristine 表單沒有填寫記錄、$er
django中處理表單的經典流程
contex 用戶 通過 eth ret span quest con 信息 def form_process_view(request): if request.method == ‘POST‘: # 請求為 POST,利用用戶提交的數據構造一個
tp表單的提交與驗證
地址 更多 php end user func 機制 etc spa 一、控制器如下 引用use app\index\model\User; //註意模型類名不能和控制器類名相同 public function index(){ return $this->fe
表單驗證,與多語言支持,CI
加載 load for 控制器 cati 驗證 pan conf span 表單驗證將漢化包,復制到application文件夾下的language,然後在config.php中,將語音改為simplified-chinese,和漢化包文件夾的名字一致。 對於隨漢化包帶來
Django--分頁器(paginator)、Django的用戶認證、Django的FORM表單
modelform 從數據 submit fields 個人 select method rtc 無法使用 分頁器(paginator) >>> from django.core.paginator import Paginator >>&g
Django-Django的form表單
valid blog pos ges 驗證 錯誤 form表單 技術分享 orm 註冊頁面如果用ajax來做,視圖views裏面判斷會很復雜,需要判斷各種字段,我們用form來做 form_obj,實例化form_post(form_obj)對象,一定要加上(reque
Django基礎2---url控制器模塊與views視圖模塊
appname OS 技術分享 正則表達 什麽 url art clock pycha url控制器: 主要是用於url的分發功能,如用戶輸入:127.0.0.1:8080/apptest 配置url才能使django正確識別用戶的輸入 未配置url報錯類型如下:
Django使用普通表單、Form、以及modelForm操作數據庫方式總結
信息 自定義字段 turn html 缺點 tin 顯示時間 流程 req Django使用普通表單、Form、以及modelForm操作數據庫主要應用於增刪該查的情景下,流程通用如下,只是實現方式不一樣: 進入填寫表單頁面; 在表單頁面填寫信息,並提交; 表單數
71、Django之form表單
protoc valid init title except Go doc 列表 ima Form介紹 我們之前在HTML頁面中利用form表單向後端提交數據時,都會寫一些獲取用戶輸入的標簽並且用form標簽把它們包起來。 與此同時我們在好多場景下都需要對用戶的輸入做校驗
[Django學習] Django基礎(5)_優化分頁器
優化 最小值 src div img == cti css style 一. 基本樣式 主要優化內容: #1. 當前頁高亮 #2. 顯示當前頁及其前後兩頁 #3. 顯示省略號標記 #4. 顯示首尾頁 #5. 將“頁數描述文字”放置在“頁碼欄”下方 #6. “頁碼欄”與“
JEPLUS之APP表單頁面設計——JEPLUS軟件快速開發平臺
查看 title bold water back get mage pan eight JEPLUS之APP表單頁面設計 在之前的文章中我介紹了APP裏面的列表頁面設計,今天我來介紹下APP裏面的表單頁面設計。一、效果展示二、功能詳解3
Django---簡單接受表單信息
inpu sele opp div color etl 表單 req class 普通接受信息: 接受單選的值:例如:input select 等提交過來的信息 u = request.POST.get(‘username‘,None) 接受多選: h = reque
表單隱藏域與display:none
隱藏域 display code idt 兩種 log 提交 點擊事件 rip 有時候前端進行表單填寫是分步驟的,每一步的時候其他步驟相關的表單視圖不可見; 針對"不可見",以下有兩種處理方式: ①display:none 這種方式呢,比較簡單,就是將三個步驟分3個d