Django搭建部落格(八):進階:form與 model配合使用
阿新 • • 發佈:2018-11-08
一、使用情景
在我們的後臺管理頁面中需要一個表單來提交和修改部落格,按照上一篇講的,我們可以這麼使用:
先定義一個 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):
... ...
我們來看看效果: