天天看點

Django搭建部落格(八):進階:form與 model配合使用

一、使用情景

在我們的背景管理頁面中需要一個表單來送出和修改部落格,按照上一篇講的,我們可以這麼使用:

先定義一個 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):
        ... ...           

複制

我們來看看效果:

Django搭建部落格(八):進階:form與 model配合使用