參考教程
目前打開詳情頁面例嘱,會報錯。所以就來解決一下這個問題。
url 用正則表達式配置
文章詳情頁的的 url 是一個正則表達式际看。
from django.conf.urls import url
from . import views
app_name = 'blog'
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^post/(?P<pk>[0-9]+)/$', views.detail, name='detail'),
]
(?P<name>...) 是正則表達式的分組的命名模式,取此分組中的內(nèi)容既可以使用索引也可以使用 name
m = re.search(r'^post/(?P<pk>[0-9]+)/$', "post/3/")
if m:
m.groupdict()
>>> {'pk': '3'}
app_name='blog'
app_name='blog' 告訴 Django 這個 urls.py 模塊是屬于 blog 應(yīng)用的矢否,這種技術(shù)叫做視圖函數(shù)命名空間仲闽。我們看到 blog\urls.py 目前有兩個視圖函數(shù),并且通過 name 屬性給這些視圖函數(shù)取了個別名僵朗,分別是 index赖欣、detail。但是一個復(fù)雜的 Django 項目可能不止這些視圖函數(shù)验庙,例如一些第三方應(yīng)用中也可能有叫 index顶吮、detail 的視圖函數(shù),那么怎么把它們區(qū)分開來粪薛,防止沖突呢悴了?方法就是通過 app_name 來指定命名空間,命名空間具體如何使用將在下面介紹。如果你忘了在 blog\urls.py 中添加這一句湃交,接下來你可能會得到一個 NoMatchReversed 異常熟空。
django reverse 函數(shù)
參考文檔,https://docs.djangoproject.com/en/2.1/ref/urlresolvers/
blog/models.py
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from django.utils.six import python_2_unicode_compatible
@python_2_unicode_compatible
class Post(models.Model):
...
def __str__(self):
return self.title
# 自定義 get_absolute_url 方法
# 記得從 django.urls 中導(dǎo)入 reverse 函數(shù)
def get_absolute_url(self):
s = reverse('blog:detail', kwargs={'pk': self.pk})
return s
注意到 URL 配置中的 url(r'^post/(?P<pk>[0-9]+)/$', views.detail, name='detail') 巡揍,我們設(shè)定的 name='detail' 在這里派上了用場痛阻。看到這個 reverse 函數(shù)腮敌,它的第一個參數(shù)的值是 'blog:detail'阱当,意思是 blog 應(yīng)用下的 name=detail 的函數(shù),由于我們在上面通過 app_name = 'blog' 告訴了 Django 這個 URL 模塊是屬于 blog 應(yīng)用的糜工,因此 Django 能夠順利地找到 blog 應(yīng)用下 name 為 detail 的視圖函數(shù)弊添,于是 reverse 函數(shù)會去解析這個視圖函數(shù)對應(yīng)的 URL,我們這里 detail 對應(yīng)的規(guī)則就是 post/(?P<pk>[0-9]+)/ 這個正則表達式捌木,而正則表達式部分會被后面?zhèn)魅氲膮?shù) pk 替換油坝,所以,如果 Post 的 id(或者 pk刨裆,這里 pk 和 id 是等價的) 是 255 的話澈圈,那么 get_absolute_url 函數(shù)返回的就是 /post/255/ ,這樣 Post 自己就生成了自己的 URL帆啃。
反復(fù)看了幾遍瞬女,才明白為什么起名叫 reverse 函數(shù)。一般而言努潘,都是根據(jù) url 來查找視圖函數(shù)的诽偷。而 reverse 函數(shù)又在中間包了一層。在html 中這樣配置:
<a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
Django 的模板解釋器肯定會調(diào)用 post.get_absolute_url 這個函數(shù)疯坤,這個函數(shù)的輸出是 post/1
报慕,根據(jù)這個路徑再去路由里面去查找相應(yīng)的視圖函數(shù)。這個過程比起直接在 html 中硬編碼压怠,多包了一層函數(shù)眠冈,使得當 url 地址有變動時,不用去滿世界改模板菌瘫。
總結(jié)一下洋闽,這個 reverse 函數(shù)是寫在 models 下面的,reverse 的第一個函數(shù)指明了視圖函數(shù)的位置突梦,其他的可以傳點參數(shù)诫舅。
修改視圖模板
主要是把 single.html 改為 detail.html , 把詳情頁面的鏈接指向 {{ post.get_absolute_url }}。然后我自己又做了一些視圖的繼承與拆分宫患。