摘要:本節(jié)接上周的文檔學(xué)習(xí)小組博客開(kāi)發(fā)實(shí)戰(zhàn)第一周教程編寫博客的首頁(yè)面,我們繼續(xù)給博客添加功能,以及改善前面不合理的部分。返回該視圖要顯示的對(duì)象。目前小組正在完成第一個(gè)項(xiàng)目,本文即是該項(xiàng)目第二周的相關(guān)文檔。
本教程內(nèi)容已過(guò)時(shí),更新版教程請(qǐng)?jiān)L問(wèn): django 博客開(kāi)發(fā)入門教程。
上周我們完成了博客的 Model 部分,以及 Blog 的首頁(yè)視圖 IndexView。
本節(jié)接上周的文檔 Django 學(xué)習(xí)小組:博客開(kāi)發(fā)實(shí)戰(zhàn)第一周教程 —— 編寫博客的首頁(yè)面,我們繼續(xù)給博客添加功能,以及改善前面不合理的部分。本教程將帶你完成 Blog 的詳情頁(yè)面,即用戶點(diǎn)擊首頁(yè)的文章標(biāo)題或者閱讀全文按鈕將跳轉(zhuǎn)到文章的詳情頁(yè)面來(lái)閱讀整篇文章。其次將調(diào)整一些目錄結(jié)構(gòu)以使其在實(shí)踐應(yīng)用中更加合理。
重寫URL提示:在閱讀教程的過(guò)程中,如有任何問(wèn)題請(qǐng)?jiān)L問(wèn)我們項(xiàng)目的 GithHub 或評(píng)論留言以獲取幫助,本教程的相關(guān)代碼已全部上傳在 Github。如果你對(duì)我們的教程或者項(xiàng)目有任何改進(jìn)建議,請(qǐng)您通過(guò)隨時(shí)告知我們。更多交流請(qǐng)加入我們的郵件列表[email protected]。
對(duì)于一個(gè)有多個(gè) app 的項(xiàng)目,把所有的 urlpatterns 都放在項(xiàng)目的 urls.py 似乎不是一個(gè)很合適的選擇,為此我們需要在 blog 文件夾下新建一個(gè)文件 urls.py ,把跟這個(gè) app 相關(guān)的 urlpatterns 都放在這個(gè)文件里。
文件中的 urlpatterns 看不懂暫時(shí)沒(méi)關(guān)系,下面很快就會(huì)介紹它。
# blog/urls.py from django.conf.urls import url from blog import views urlpatterns = [ url(r"^blog/$", views.IndexView.as_view(), name="index"), url(r"^blog/article/(?Pd+)$", views.ArticleDetailView.as_view(), name="detail"), url(r"^blog/category/(?P d+)$", views.CategoryView.as_view(), name="category"), ] # 使用(?P<>d+)的形式捕獲值給<>中得參數(shù),比如(?P d+),當(dāng)訪問(wèn)/blog/article/3時(shí),將會(huì)將3捕獲給article_id,這個(gè)值會(huì)傳到views.ArticleDetailView,這樣我們就可以判斷展示哪個(gè)Article了
然后在項(xiàng)目的 urls.py 中包含(include)它:
# DjangoBlog/blog_project/urls.py from django.conf.urls import url, include from django.contrib import admin from blog import views urlpatterns = [ url(r"^admin/", admin.site.urls), url(r"", include("blog.urls", namespace="blog", app_name="blog")) ] # 其中namespace參數(shù)為我們指定了命名空間,這說(shuō)明這個(gè)urls.py中的url是blog app下的,這樣即使不同的app下有相同url也不會(huì)沖突了。
這樣,我們就重寫了 URL,看起來(lái)是不是更有條理了?
新增文章詳情頁(yè)class ArticleDetailView(DetailView): # Django有基于類的視圖DetailView,用于顯示一個(gè)對(duì)象的詳情頁(yè),我們繼承它 model = Article # 指定視圖獲取哪個(gè)model template_name = "blog/detail.html" # 指定要渲染的模板文件 context_object_name = "article" # 在模板中需要使用的上下文名字 pk_url_kwarg = "article_id" # 這里注意,pk_url_kwarg用于接收一個(gè)來(lái)自u(píng)rl中的主鍵,然后會(huì)根據(jù)這個(gè)主鍵進(jìn)行查詢 # 我們之前在urlpatterns已經(jīng)捕獲article_id # 指定以上幾個(gè)屬性,已經(jīng)能夠返回一個(gè)DetailView視圖了,為了讓文章以markdown形式展現(xiàn),我們重寫get_object()方法。 def get_object(self): obj = super(ArticleDetailView, self).get_object() obj.body = markdown2.markdown(object.body) return obj
get_object() 返回該視圖要顯示的對(duì)象。如果有設(shè)置 queryset,該queryset 將用于對(duì)象的源;否則,將使用get_queryset(). get_object()從視圖的所有參數(shù)中查找 pk_url_kwarg 參數(shù); 如果找到了這個(gè)參數(shù),該方法使用這個(gè)參數(shù)的值執(zhí)行一個(gè)基于主鍵的查詢。
新建一個(gè)模板 detail.html 來(lái)展示我們的文章詳情
blog/templates/blog/detail.html {% extends "base.html" %} {% block content %}{% endblock %}{{ article.title }}
{{ article.last_modified_time|date:"Y年n月d日" }}{{ article.body |safe }}
整個(gè)執(zhí)行流程就是這樣的:
假設(shè)用戶要訪問(wèn)某篇文章,比如他點(diǎn)擊了某篇文章的標(biāo)題,在模板文件中(首頁(yè)的模板,代碼可以參見(jiàn) GitHub 上的 index.html),他點(diǎn)擊的就是這樣一個(gè)標(biāo)簽:
{{ article.title }}
標(biāo)簽是一個(gè)超鏈接,用戶點(diǎn)擊后會(huì)跳轉(zhuǎn)到由 href 指定的 url,這里我們使用了 django 自帶的模板標(biāo)簽 url 標(biāo)簽,它會(huì)自動(dòng)解析 blog:detail 這個(gè)視圖函數(shù)對(duì)應(yīng)的 url,并且把 article.pk(文章的主鍵)傳遞給detail 視圖函數(shù) 。detail 的 url 是這樣定義的:
url(r"^blog/article/(?Pd+)$", views.ArticleDetailView.as_view(), name="detail")
假設(shè)用戶點(diǎn)擊了第三篇文章,那么該 url 會(huì)被解析成:/blog/article/3,其中 3 被傳遞給了詳情頁(yè)面視圖函數(shù)。
現(xiàn)在視圖函數(shù)被調(diào)用,它首先根據(jù)傳給它的參數(shù)獲自動(dòng)調(diào)用 get_object 方法取到文章的 model,然后根據(jù) context_object_name = "article" 把 article 加入到上下文中(可以理解為攜帶著這個(gè)變量及其值并要傳遞給模板文件的對(duì)象,模板文件從這個(gè)對(duì)象中取出模板變量對(duì)應(yīng)的值并替換。),之后渲染 template_name = "blog/detail.html" 指定的模板文件,至此用戶就跳轉(zhuǎn)到了文章詳情頁(yè),效果如下:
新增分類視圖點(diǎn)擊某個(gè)分類,展示該分類下所有文章,其邏輯和首頁(yè)展示全部文章列表是一樣的,唯一不同的是我們獲取的不是全部文章,而是該分類下的文章。代碼如下:
class CategoryView(ListView): # 繼承自ListView,用于展示一個(gè)列表 template_name = "blog/index.html" # 指定需要渲染的模板 context_object_name = "article_list" # 指定模板中需要使用的上下文對(duì)象的名字 def get_queryset(self): #get_queryset 的作用已在第一篇中有介紹,不再贅述 article_list = Article.objects.filter(category=self.kwargs["cate_id"],status="p") # 注意在url里我們捕獲了分類的id作為關(guān)鍵字參數(shù)(cate_id)傳遞給了CategoryView,傳遞的參數(shù)在kwargs屬性中獲取。 for article in article_list: article.body = markdown2.markdown(article.body, ) return article_list # 給視圖增加額外的數(shù)據(jù) def get_context_data(self, **kwargs): kwargs["category_list"] = Category.objects.all().order_by("name") # 增加一個(gè)category_list,用于在頁(yè)面顯示所有分類,按照名字排序 return super(CategoryView, self).get_context_data(**kwargs)
這里我們復(fù)用的是主頁(yè)的模板(因?yàn)檎故镜臇|西都是一樣的),點(diǎn)擊相應(yīng)的分類,展示該分類下所有文章。同樣別忘了如果要用戶點(diǎn)擊分類按鈕跳轉(zhuǎn)到分類頁(yè)面的話,要指定 標(biāo)簽的 href 屬性,善用 url 模板標(biāo)簽,防止硬編碼 url,像這樣:
分類顯示效果如下,顯示分類二下的全部文章:
接下來(lái)做什么?至此,我們完成了博客的首頁(yè),詳情展示頁(yè)以及分類功能,基本的框架算是完成了。接下來(lái)我們會(huì)為我們的 Blog 添加更多高級(jí)的功能,包括有標(biāo)簽云、文章歸檔、文章分頁(yè)等。敬請(qǐng)期待我們下一周的教程。如果你希望為你的 Blog 添加其他更加獨(dú)特的功能,也請(qǐng)隨時(shí)告訴我們。
Django學(xué)習(xí)小組簡(jiǎn)介django學(xué)習(xí)小組是一個(gè)促進(jìn) django 新手互相學(xué)習(xí)、互相幫助的組織。
小組在一邊學(xué)習(xí) django 的同時(shí)將一起完成幾個(gè)項(xiàng)目,包括:
一個(gè)簡(jiǎn)單的 django 博客,用于發(fā)布小組每周的學(xué)習(xí)和開(kāi)發(fā)文檔;
django中國(guó)社區(qū),為國(guó)內(nèi)的 django 開(kāi)發(fā)者們提供一個(gè)長(zhǎng)期維護(hù)的 django 社區(qū);
上面所說(shuō)的這個(gè)社區(qū)類似于 segmentfault 和 stackoverflow ,但更加專注(只專注于 django 開(kāi)發(fā)的問(wèn)題)。
目前小組正在完成第一個(gè)項(xiàng)目,本文即是該項(xiàng)目第二周的相關(guān)文檔。
更多的信息請(qǐng)關(guān)注我們的?github 組織,本教程項(xiàng)目的相關(guān)源代碼也已上傳到 github 上。
同時(shí),你也可以加入我們的郵件列表[email protected]?,隨時(shí)關(guān)注我們的動(dòng)態(tài)。我們會(huì)將每周的詳細(xì)開(kāi)發(fā)文檔和代碼通過(guò)郵件列表發(fā)出。
如有任何建議,歡迎提 issue,歡迎 fork,pr,當(dāng)然也別忘了 star 哦!
合作推廣本系列教程將首發(fā)于 編程派 微信公眾號(hào),編程派(微信號(hào):codingpy)是一個(gè)專注Python編程的公眾號(hào),每天更新有關(guān)Python的國(guó)外教程和優(yōu)質(zhì)書籍等精選干貨,掃描下方二維碼以關(guān)注:
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/37991.html
摘要:本教程內(nèi)容已過(guò)時(shí),更新版教程請(qǐng)?jiān)L問(wèn)博客開(kāi)發(fā)入門教程。我們的評(píng)論表單放在中,評(píng)論成功后返回到原始提交頁(yè)面。學(xué)習(xí)小組簡(jiǎn)介學(xué)習(xí)小組是一個(gè)促進(jìn)新手互相學(xué)習(xí)互相幫助的組織。 本教程內(nèi)容已過(guò)時(shí),更新版教程請(qǐng)?jiān)L問(wèn): django 博客開(kāi)發(fā)入門教程。 通過(guò)前四周的時(shí)間我們開(kāi)發(fā)了一個(gè)簡(jiǎn)單的個(gè)人 Blog,前幾期教程地址: 第一周:Django 學(xué)習(xí)小組:博客開(kāi)發(fā)實(shí)戰(zhàn)第一周教程 —— 編寫博客的 Mode...
摘要:本教程內(nèi)容已過(guò)時(shí),更新版教程請(qǐng)?jiān)L問(wèn)博客開(kāi)發(fā)入門教程。我們的評(píng)論表單放在中,評(píng)論成功后返回到原始提交頁(yè)面。學(xué)習(xí)小組簡(jiǎn)介學(xué)習(xí)小組是一個(gè)促進(jìn)新手互相學(xué)習(xí)互相幫助的組織。 本教程內(nèi)容已過(guò)時(shí),更新版教程請(qǐng)?jiān)L問(wèn): django 博客開(kāi)發(fā)入門教程。 通過(guò)前四周的時(shí)間我們開(kāi)發(fā)了一個(gè)簡(jiǎn)單的個(gè)人 Blog,前幾期教程地址: 第一周:Django 學(xué)習(xí)小組:博客開(kāi)發(fā)實(shí)戰(zhàn)第一周教程 —— 編寫博客的 Mode...
摘要:本教程內(nèi)容已過(guò)時(shí),更新版教程請(qǐng)?jiān)L問(wèn)博客開(kāi)發(fā)入門教程。表示降序排列,默認(rèn)是升序排列。學(xué)習(xí)小組簡(jiǎn)介學(xué)習(xí)小組是一個(gè)促進(jìn)新手互相學(xué)習(xí)互相幫助的組織。我們會(huì)將每周的詳細(xì)開(kāi)發(fā)文檔和代碼通過(guò)郵件列表發(fā)出。 本教程內(nèi)容已過(guò)時(shí),更新版教程請(qǐng)?jiān)L問(wèn): django 博客開(kāi)發(fā)入門教程。 通過(guò)前四周的時(shí)間我們開(kāi)發(fā)了一個(gè)簡(jiǎn)單的個(gè)人 Blog,教程地址: 第一周:Django 學(xué)習(xí)小組:博客開(kāi)發(fā)實(shí)戰(zhàn)第一周教程 ——...
摘要:本教程首先介紹兩個(gè)項(xiàng)目中遇到的通用視圖和。語(yǔ)句的作用是添加了到上下文中,還要把默認(rèn)的一些上下文變量也返回給視圖函數(shù),以便其后續(xù)處理。 通過(guò)三周的時(shí)間我們開(kāi)發(fā)了一個(gè)簡(jiǎn)單的個(gè)人 Blog,教程地址: 第一周:Django 學(xué)習(xí)小組:博客開(kāi)發(fā)實(shí)戰(zhàn)第一周教程 —— 編寫博客的 Model 和首頁(yè)面 第二周:Django 學(xué)習(xí)小組:博客開(kāi)發(fā)實(shí)戰(zhàn)第二周教程 —— 博客詳情頁(yè)面和分類頁(yè)面 第三周:D...
摘要:本教程內(nèi)容已過(guò)時(shí),更新版教程請(qǐng)?jiān)L問(wèn)博客開(kāi)發(fā)入門教程。當(dāng)分頁(yè)較多時(shí),總是顯示當(dāng)前頁(yè)及其前幾頁(yè)和后幾頁(yè)的頁(yè)碼教程中使用的是兩頁(yè),其他頁(yè)碼用省略號(hào)代替。 本教程內(nèi)容已過(guò)時(shí),更新版教程請(qǐng)?jiān)L問(wèn): django 博客開(kāi)發(fā)入門教程。 摘要:前兩期教程我們實(shí)現(xiàn)了博客的 Model 部分,以及 Blog 的首頁(yè)視圖 IndexView,詳情頁(yè)面 DetailView,以及分類頁(yè)面 CategoryVi...
閱讀 3116·2021-11-24 09:38
閱讀 1374·2021-09-22 15:27
閱讀 3002·2021-09-10 10:51
閱讀 1543·2021-09-09 09:33
閱讀 949·2021-08-09 13:47
閱讀 2120·2019-08-30 13:05
閱讀 920·2019-08-29 15:15
閱讀 2486·2019-08-29 12:21