到目前為止我們已經完成了一個django應用的所有基礎部分。 包括url配置、視圖、模型和模板。接下來開始繼續完善我們的博客系統了。
首先我們需要一個顯示每篇文章的詳細頁面,對不?
文章詳情
對於首頁每一篇文章,我們希望點擊標題后可以進入該文章的閱讀頁面。修改post_list.html中的標題href如下:
1 |
<h1><a href="{% url 'blog.views.post_detail' pk=post.pk %}">{{ post.title }}</a></h1> |
我來詳細解釋下這個{% url ‘blog.views.post_detail’ pk=post.pk %},{% %} 表示使用django模板標簽而不是普通的HTML文字,這里我們使用了url標簽來生成真正的url鏈接。 blog.views.post_detail是視圖的全路徑。
url配置
我們希望文章詳細頁面的鏈接類似這樣:http://127.0.0.1:8000/post/1/
修改blog/urls.py為下面的這樣:
1 |
from django.conf.urls import patterns, include, url |
這個看起來有點復雜,我們來解釋下:
- ^ 代表的是開始
- post/表示URL開始必須是post/
- (?P[0-9]+) – 這部分比較復雜。它表示一個命名參數pk, 它會捕獲url中的這部分然后將它賦值給pk參數傳遞給視圖。 [0-9]表示這部分必須是數字,+表示至少1個數字,也可以多個數字。
- / – 然后后面接/
- $ – URL的結尾
post_detail視圖
現在去訪問還會報錯,因為我們還沒有post_detail這個視圖。現在我們開始定義它。
修改文件blog/views.py如下:
1 |
from django.shortcuts import render, get_object_or_404 |
post_detail模板
然后再增加模板blog/templates/blog/post_detail.html:
1 |
{% extends 'blog/base.html' %} |
這次我們還是采用模板繼承方式,這里我們還用到了模板標簽if,這是一個條件判斷的標簽。
OK,一切都已准備就緒,現在打開首頁,然后點擊任意一篇文章標題看下結果:
搞定!!
創建文章
最后一件事就是要實現文章創建和更新操作,這是博客系統最核心的功能。django自帶的admin很酷,但是確很難定制和美化。 forms非常強大和自由,我們可以好好的利用它來實現我們需要的功能。
forms一個很好的特性就是它既能從頭定義一個表單,也能創建一個ModelForm來將表單結果保存為一個模型。 而這正是我們想要的功能,我們可以創建一個ModelForm來將表單轉換為一個Post模型。
表單對象的定義放在forms.py文件中。我們需要在blog文件夾中創建forms.py文件,結構如下:
blog
└── forms.py
在里面寫入如下內容:
1 |
from django import forms |
PostForm需要繼承自forms.ModelForm,這樣django就能實現某些神奇的效果。 在里面我們定義了元類Meta,然后指定model為Post,還有字段為title和text。 因為我們只需要對外暴露標題和內容,至於作者就是登陸用戶了,而發布日期和創建日期就是提交時間。
下面我們要做的就是在view中使用我們的form,並在template中顯示它。
我們繼續走四個步驟:頁面上添加鏈接, 外加“三部曲”。基本上每個新功能的增加時只需要增加這四個東東就行了。
增加鏈接
打開blog/templates/blog/base.html,在名字為page-header的div中添加一個新增文章的鏈接:
1 |
<a href="{% url 'blog.views.post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a> |
這時候你的base.html應該是這樣的:
1 |
{% load staticfiles %} |
URL
打開blog/urls.py文件,添加一條配置:
1 |
url(r'^post/new/$', views.post_new, name='post_new'), |
現在它的內容應該是這樣的:
1 |
from django.conf.urls import patterns, include, url |
post_new視圖
打開文件blog/views.py,先引入PostForm
1 |
from .forms import PostForm |
然后增加視圖:
1 |
def post_new(request): |
post_edit.html模板
在blog/templates/blog目錄新建一個post_edit.html頁面,然后寫入下列內容:
1 |
{% extends 'blog/base.html' %} |
保存后,刷新首頁,點擊加號那個鏈接可以看到如下頁面:
但是當你寫了文字后點擊保存后會發現又跑到這個新建頁面來了。 因為這個是POST提交,但是URL還是一樣的,又會跑到post_new那個視圖中去, 這個視圖只做了頁面跳轉來到了這個新建頁面。
那么我們需要修改下post_new視圖邏輯了:
在頭部先引入下面的依賴:
1 |
from django.core.urlresolvers import reverse |
然后修改post_new視圖如下:
1 |
def post_new(request): |
上面表示我添加完一篇文章后自動跳轉到文章詳情頁面去,保存后效果:
表單驗證
由於我們在Post模型中已經定義了title和text是必需的,django會自動幫我們做驗證。 看下如果我們不輸入title和text直接提交會怎樣:
django已經自動幫我們做了驗證,是不是很酷呢?
編輯文章
我們剛剛已經實現了新建文章的功能,那么如果是編輯修改文章呢。接下來我會快速的講解這個流程,現在你應該是可以看得懂的了。
首先打開blog/templates/blog/post_detail.html,添加一行:
1 |
<a class="btn btn-default" href="{% url 'post_edit' pk=post.pk %}"> |
現在它的內容是這樣的:
1 |
{% extends 'blog/base.html' %} |
然后修改blog/urls.py文件,添加一條:
1 |
url(r'^post/(?P<pk>[0-9]+)/edit/$', views.post_edit, name='post_edit'), |
我們會重用模板blog/templates/blog/post_edit.html, 因此只需要修改下view就可以了,打開文件blog/views.py,將下面的內容添加到最后:
1 |
def post_edit(request, pk): |
這個跟post_new幾乎一模一樣,先通過主鍵查到文章:post = get_object_or_404(Post, pk=pk)
, 然后我們在提交和進入編輯頁面的時候都將post作為instance參數傳遞給PostForm。
OK,現在讓我們來測試下效果:
完美,恭喜你!你的應用已經變得越來越酷了。