一、使用情景
在我們的背景管理頁面中需要一個表單來送出和修改部落格,按照上一篇講的,我們可以這麼使用:
先定義一個 Form類,包括标題、标簽和内容三個字段:
class ArticleForm(forms.Form):
title = forms.CharField(label='标題', max_length=50)
tags = forms.CharField(label='标簽', max_length=50)
content = TextFiled(label='内容')
複制
然後在頁面中就可以直接使用 form,在送出表單時,我們還需要将各個字段指派給 model的對應字段。
在修改文章的頁面我們需要先将表格填充好,再渲染頁面。
這時我們的表單還隻有幾個字段,工作量并不大,但是如果表單的字段增加到十幾個,工作量就有點大了。
幸好 Django為我們提供了
ModelForm
類,可以根據已存在的 Model類來自動地建立
Form
類。
二、使用 ModelForm
使用
ModelForm
很簡單,我們隻需要建立一個元類并給對應的屬性指派即可,如下:
class ArticleForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'tags', 'content']
複制
我們可以通過
fields
來确定需要輸入的字段,也可以通過
exclude
來設定不需要輸入的字段。
這樣當我們送出表單之後,隻需要調用
ArticleForm
的
save
方法即可将添加的部落格儲存到資料庫中去。
不過我們這裡有兩個字段沒有添加到 form表單中去,是以在調用
save
方法時會報錯,這時隻需重載
save
方法即可:
class ArticleForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'tags', 'content']
def save(self, commit=True):
key = abs(hash(self.instance.title))
date = datetime.datetime.now().strftime('%Y-%m-%d')
self.instance.key = key
self.instance.date = key
self.instance.save()
return self.instance
複制
在視圖函數中我們可以這樣使用:
def addArticle(request):
if request.method == 'GET':
form = ArticleForm()
return render(
request,
'myblog/add_article.html',
{'pagedata':
{'form':form}
}
)
elif request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('article_list'))
else:
return render(
request,
'myblog/add_article.html',
{'pagedata':
{'form': form}
}
)
複制
在編輯文章的頁面,我們可以直接将查詢到的
Post
類傳遞給
ArticleForm
的
instance
參數。
instance
參數将會指派給
ArticleForm
的
instance
屬性,我們上面重載
save
方法時就用到了
instance
屬性。
def modifyArticle(request, key):
if request.method == 'GET':
post_list = Post.objects.filter(key=key)
if len(post_list) == 0:
return HttpResponse('文章不存在')
else:
article_form = ArticleForm(instance=post_list[0])
... ...
複制
如果想指定某個字段的樣式,可以通過
Meta
類的
widgets
屬性來指定,如下:
class TagInput(widgets.Input):
input_type = 'text'
template_name = 'myblog/widgets/input.html'
class ArticleForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'tags', 'content']
widgets = {
'tags': TagInput
}
def save(self, commit=True):
... ...
複制
我們來看看效果:
