国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Django 博客開發(fā)教程 8 - 博客文章詳情頁

pkwenda / 3118人閱讀

摘要:對文章詳情視圖而言,每篇文章對應(yīng)著不同的。在博客文章詳情頁追夢人物的博客的評論區(qū)留言。將問題的詳細描述通過郵件發(fā)送到,一般會在小時內(nèi)回復(fù)。更多教程,請訪問追夢人物的博客。

首頁展示的是所有文章的列表,當用戶看到感興趣的文章時,他點擊文章的標題或者繼續(xù)閱讀的按鈕,應(yīng)該跳轉(zhuǎn)到文章的詳情頁面來閱讀文章的詳細內(nèi)容。現(xiàn)在讓我們來開發(fā)博客的詳情頁面,有了前面的基礎(chǔ),開發(fā)流程都是一樣的了:首先配置 URL,即把相關(guān)的 URL 和視圖函數(shù)綁定在一起,然后實現(xiàn)視圖函數(shù),編寫模板并讓視圖函數(shù)渲染模板。

設(shè)計文章詳情頁的 URL

回顧一下我們首頁視圖的 URL,在 blogurls.py 文件里,我們寫了:

blog/urls.py

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r"^$", views.index, name="index"),
]

首頁視圖匹配的 URL 去掉域名后其實就是一個空的字符串。對文章詳情視圖而言,每篇文章對應(yīng)著不同的 URL。比如我們可以把文章詳情頁面對應(yīng)的視圖設(shè)計成這個樣子:當用戶訪問 <網(wǎng)站域名>/post/1/ 時,顯示的是第一篇文章的內(nèi)容,而當用戶訪問 <網(wǎng)站域名>/post/2/ 時,顯示的是第二篇文章的內(nèi)容,這里數(shù)字代表了第幾篇文章,也就是數(shù)據(jù)庫中 Post 記錄的 id 值。下面依照這個規(guī)則來綁定 URL 和視圖:

blog/urls.py

from django.conf.urls import url

from . import views

app_name = "blog"
urlpatterns = [
    url(r"^$", views.index, name="index"),
    url(r"^post/(?P[0-9]+)/$", views.detail, name="detail"),
]

Django 使用正則表達式來匹配用戶訪問的網(wǎng)址。這里 r"^post/(?P[0-9]+)/$" 整個正則表達式剛好匹配我們上面定義的 URL 規(guī)則。這條正則表達式的含義是,以 post/ 開頭,后跟一個至少一位數(shù)的數(shù)字,并且以 / 符號結(jié)尾,如 post/1/、 post/255/ 等都是符合規(guī)則的,[0-9]+ 表示一位或者多位數(shù)。此外這里 (?P[0-9]+) 表示命名捕獲組,其作用是從用戶訪問的 URL 里把括號內(nèi)匹配的字符串捕獲并作為關(guān)鍵字參數(shù)傳給其對應(yīng)的視圖函數(shù) detail。比如當用戶訪問 post/255/ 時(注意 Django 并不關(guān)心域名,而只關(guān)心去掉域名后的相對 URL),被括起來的部分 (?P[0-9]+) 匹配 255,那么這個 255 會在調(diào)用視圖函數(shù) detail 時被傳遞進去,實際上視圖函數(shù)的調(diào)用就是這個樣子:detail(request, pk=255)。我們這里必須從 URL 里捕獲文章的 id,因為只有這樣我們才能知道用戶訪問的究竟是哪篇文章。

可能上述的正則表達式你有點難以理解,關(guān)于正則表達式的部分并非 Django 相關(guān)的內(nèi)容,而是 Python 的內(nèi)容。Django 只是在這里使用了 Python 處理正則表達式的 re 模塊。因此如果想更好地理解 Python 中正則表達式的相關(guān)知識,請自行查看 Python 官方文檔中 re 模塊的文檔。

此外我們通過 app_name="blog" 告訴 Django 這個 urls.py 模塊是屬于 blog 應(yīng)用的,這種技術(shù)叫做視圖函數(shù)命名空間。我們看到 blogurls.py 目前有兩個視圖函數(shù),并且通過 name 屬性給這些視圖函數(shù)取了個別名,分別是 index、detail。但是一個復(fù)雜的 Django 項目可能不止這些視圖函數(shù),例如一些第三方應(yīng)用中也可能有叫 index、detail 的視圖函數(shù),那么怎么把它們區(qū)分開來,防止沖突呢?方法就是通過 app_name 來指定命名空間,命名空間具體如何使用將在下面介紹。如果你忘了在 blogurls.py 中添加這一句,接下來你可能會得到一個 NoMatchReversed 異常。

為了方便地生成上述的 URL,我們在 Post 類里定義一個 get_absolute_url 方法,注意 Post 本身是一個 Python 類,在類中我們是可以定義任何方法的。

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):
        return reverse("blog:detail", kwargs={"pk": self.pk})

注意到 URL 配置中的 url(r"^post/(?P[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[0-9]+)/ 這個正則表達式,而正則表達式部分會被后面?zhèn)魅氲膮?shù) pk 替換,所以,如果 Post 的 id(或者 pk,這里 pk 和 id 是等價的) 是 255 的話,那么 get_absolute_url 函數(shù)返回的就是 /post/255/ ,這樣 Post 自己就生成了自己的 URL。

編寫 detail 視圖函數(shù)

接下來就是實現(xiàn)我們的 detail 視圖函數(shù)了:

blog/views.py

from django.shortcuts import render, get_object_or_404
from .models import Post

def index(request):
    # ...

def detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    return render(request, "blog/detail.html", context={"post": post})

視圖函數(shù)很簡單,它根據(jù)我們從 URL 捕獲的文章 id(也就是 pk,這里 pk 和 id 是等價的)獲取數(shù)據(jù)庫中文章 id 為該值的記錄,然后傳遞給模板。注意這里我們用到了從 django.shortcuts 模塊導(dǎo)入的 get_object_or_404 方法,其作用就是當傳入的 pk 對應(yīng)的 Post 在數(shù)據(jù)庫存在時,就返回對應(yīng)的 post,如果不存在,就給用戶返回一個 404 錯誤,表明用戶請求的文章不存在。

編寫詳情頁模板

接下來就是書寫模板文件,從下載的博客模板(如果你還沒有下載,請 點擊這里 下載)中把 single.html 拷貝到 templatesblog 目錄下(和 index.html 在同一級目錄),然后改名為 detail.html。此時你的目錄結(jié)構(gòu)應(yīng)該像這個樣子:

blogproject
    manage.py
    blogproject
        __init__.py
        settings.py
        ...
    blog/
        __init__.py
        models.py
        ,,,
    templates
        blog
            index.html
            detail.html

在 index 頁面博客文章列表的標題繼續(xù)閱讀按鈕寫上超鏈接跳轉(zhuǎn)的鏈接,即文章 post 對應(yīng)的詳情頁的 URL,讓用戶點擊后可以跳轉(zhuǎn)到 detail 頁面:

templates/blog/index.html


{% empty %}
  
暫時還沒有發(fā)布的文章!
{% endfor %}

這里我們修改兩個地方,第一個是文章標題處:

{{ post.title }}

我們把 a 標簽的 href 屬性的值改成了 {{ post.get_absolute_url }}。回顧一下模板變量的用法,由于 get_absolute_url 這個方法(我們定義在 Post 類中的)返回的是 post 對應(yīng)的 URL,因此這里 {{ post.get_absolute_url }} 最終會被替換成該 post 自身的 URL。

同樣,第二處修改的是繼續(xù)閱讀按鈕的鏈接:

繼續(xù)閱讀 

這樣當我們點擊首頁文章的標題或者繼續(xù)閱讀按鈕后就會跳轉(zhuǎn)到該篇文章對應(yīng)的詳情頁面了。然而如果你嘗試跳轉(zhuǎn)到詳情頁后,你會發(fā)現(xiàn)樣式是亂的。這在 真正的 Django 博客首頁 時講過,由于我們是直接復(fù)制的模板,還沒有正確地處理靜態(tài)文件。我們可以按照介紹過的方法修改靜態(tài)文件的引入路徑,但很快你會發(fā)現(xiàn)在任何頁面都是需要引入這些靜態(tài)文件,如果每個頁面都要修改會很麻煩,而且代碼都是重復(fù)的。下面就介紹 Django 模板繼承的方法來幫我們消除這些重復(fù)操作。

模板繼承

我們看到 index.html 文件和 detail.html 文件除了 main 標簽包裹的部分不同外,其它地方都是相同的,我們可以把相同的部分抽取出來,放到 base.html 里。首先在 templates 目錄下新建一個 base.html 文件,這時候你的項目目錄應(yīng)該變成了這個樣子:

blogproject
    manage.py
    blogproject
        __init__.py
        settings.py
        ...
    blog
        __init__.py
        models.py
        ,,,
    templates
        base.html
        blog
            index.html
            detail.html

把 index.html 的內(nèi)容全部拷貝到 base.html 文件里,然后刪掉 main 標簽包裹的內(nèi)容,替換成如下的內(nèi)容。

templates/base.html

...
{% block main %} {% endblock main %}
...

這里 block 也是一個模板標簽,其作用是占位。比如這里的 {% block main %}{% endblock main %} 是一個占位框,main 是我們給這個 block 取的名字。下面我們會看到 block 標簽的作用。同時我們也在 aside 標簽下加了一個 {% block toc %}{% endblock toc %} 占位框,因為 detail.html 中 aside 標簽下會多一個目錄欄。當 {% block toc %}{% endblock toc %} 中沒有任何內(nèi)容時,{% block toc %}{% endblock toc %} 在模板中不會顯示。但當其中有內(nèi)容是,模板就會顯示 block 中的內(nèi)容。

在 index.html 里,我們在文件最頂部使用 {% extends "base.html" %} 繼承 base.html,這樣就把 base.html 里的代碼繼承了過來,另外在 {% block main %}{% endblock main %} 包裹的地方填上 index 頁面應(yīng)該顯示的內(nèi)容:

templates/blog/index.html

{% extends "base.html" %}

{% block main %}
    {% for post in post_list %}
        
...
{% empty %}
暫時還沒有發(fā)布的文章!
{% endfor %} {% endblock main %}

這樣 base.html 里的代碼加上 {% block main %}{% endblock main %} 里的代碼就和最開始 index.html 里的代碼一樣了。這就是模板繼承的作用,公共部分的代碼放在 base.html 里,而其它頁面不同的部分通過替換 {% block main %}{% endblock main %} 占位標簽里的內(nèi)容即可。

如果你對這種模板繼承還是有點糊涂,可以把這種繼承和 Python 中類的繼承類比。base.html 就是父類,index.html 就是子類。index.html 繼承了 base.html 中的全部內(nèi)容,同時它自身還有一些內(nèi)容,這些內(nèi)容就通過 “覆寫” {% block main %}{% endblock main %}(把 block 看做是父類的屬性)的內(nèi)容添加即可。

detail 頁面處理起來就簡單了,同樣繼承 base.html ,在 {% block main %}{% endblock main %} 里填充 detail.html 頁面應(yīng)該顯示的內(nèi)容,以及在 {% block toc %}{% endblock toc %} 中填寫 base.html 中沒有的目錄部分的內(nèi)容。不過目前的目錄只是占位數(shù)據(jù),我們在以后會實現(xiàn)如何從文章中自動摘取目錄。

templates/blog/detail.html

{% extends "base.html" %}

{% block main %}
    
...
...
{% endblock main %} {% block toc %} {% endblock toc %}

修改 article 標簽下的一些內(nèi)容,讓其顯示文章的實際數(shù)據(jù):

再次從首頁點擊一篇文章的標題或者繼續(xù)閱讀按鈕跳轉(zhuǎn)到詳情頁面,可以看到預(yù)期效果了!

總結(jié)

本章節(jié)的代碼位于:Step8: blog detail view。

如果遇到問題,請通過下面的方式尋求幫助。

在 博客文章詳情頁- 追夢人物的博客 的評論區(qū)留言。

將問題的詳細描述通過郵件發(fā)送到 djangostudyteam@163.com,一般會在 24 小時內(nèi)回復(fù)。

更多Django 教程,請訪問 追夢人物的博客。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/44397.html

相關(guān)文章

  • Django 學習小組:博客開發(fā)實戰(zhàn)第二周教程 —— 實現(xiàn)博客詳情面和分類

    摘要:本節(jié)接上周的文檔學習小組博客開發(fā)實戰(zhàn)第一周教程編寫博客的首頁面,我們繼續(xù)給博客添加功能,以及改善前面不合理的部分。返回該視圖要顯示的對象。目前小組正在完成第一個項目,本文即是該項目第二周的相關(guān)文檔。 本教程內(nèi)容已過時,更新版教程請訪問: django 博客開發(fā)入門教程。 上周我們完成了博客的 Model 部分,以及 Blog 的首頁視圖 IndexView。 本節(jié)接上周的文檔 Djan...

    ingood 評論0 收藏0
  • Django 學習小組:博客開發(fā)實戰(zhàn)第五周教程 —— 實現(xiàn)評論功能

    摘要:本教程內(nèi)容已過時,更新版教程請訪問博客開發(fā)入門教程。我們的評論表單放在中,評論成功后返回到原始提交頁面。學習小組簡介學習小組是一個促進新手互相學習互相幫助的組織。 本教程內(nèi)容已過時,更新版教程請訪問: django 博客開發(fā)入門教程。 通過前四周的時間我們開發(fā)了一個簡單的個人 Blog,前幾期教程地址: 第一周:Django 學習小組:博客開發(fā)實戰(zhàn)第一周教程 —— 編寫博客的 Mode...

    CoderStudy 評論0 收藏0
  • Django 學習小組:博客開發(fā)實戰(zhàn)第五周教程 —— 實現(xiàn)評論功能

    摘要:本教程內(nèi)容已過時,更新版教程請訪問博客開發(fā)入門教程。我們的評論表單放在中,評論成功后返回到原始提交頁面。學習小組簡介學習小組是一個促進新手互相學習互相幫助的組織。 本教程內(nèi)容已過時,更新版教程請訪問: django 博客開發(fā)入門教程。 通過前四周的時間我們開發(fā)了一個簡單的個人 Blog,前幾期教程地址: 第一周:Django 學習小組:博客開發(fā)實戰(zhàn)第一周教程 —— 編寫博客的 Mode...

    kumfo 評論0 收藏0
  • Django 博客開發(fā)教程 12 - 評論

    摘要:創(chuàng)建了數(shù)據(jù)庫模型就要遷移數(shù)據(jù)庫,遷移數(shù)據(jù)庫的命令也在前面講過。如果表單對應(yīng)有一個數(shù)據(jù)庫模型例如這里的評論表單對應(yīng)著評論模型,那么使用類會簡單很多,這是為我們提供的方便。表明這個表單對應(yīng)的數(shù)據(jù)庫模型是類。 創(chuàng)建評論應(yīng)用 相對來說,評論其實是另外一個比較獨立的功能。Django 提倡,如果功能相對比較獨立的話,最好是創(chuàng)建一個應(yīng)用,把相應(yīng)的功能代碼寫到這個應(yīng)用里。我們的第一個應(yīng)用叫 blog...

    wangbinke 評論0 收藏0
  • Django 學習小組:博客開發(fā)實戰(zhàn)第三周教程——文章列表分和代碼語法高亮

    摘要:本教程內(nèi)容已過時,更新版教程請訪問博客開發(fā)入門教程。當分頁較多時,總是顯示當前頁及其前幾頁和后幾頁的頁碼教程中使用的是兩頁,其他頁碼用省略號代替。 本教程內(nèi)容已過時,更新版教程請訪問: django 博客開發(fā)入門教程。 摘要:前兩期教程我們實現(xiàn)了博客的 Model 部分,以及 Blog 的首頁視圖 IndexView,詳情頁面 DetailView,以及分類頁面 CategoryVi...

    Luosunce 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<