本教程內容已過時再芋,更新版教程請訪問: Django 博客開發(fā)入門教程。
這是 Django 博客教程的第 7 篇奠衔,在閱讀此篇教程以前谆刨,請確保你已閱讀 Django 博客教程的前 6 篇:
1. Django 博客教程:前言
2. 搭建開發(fā)環(huán)境
3. 建立我們的 django 博客應用
4. 創(chuàng)建 django 博客的數據庫模型
5. 讓 django 完成翻譯——遷移數據庫模型
6. django 博客首頁視圖
上一節(jié)編寫了 blog 的首頁視圖,并且配置了 url归斤,模板痊夭,讓 django 能夠正確地處理 http 請求并返回合適的 http 響應。但是我們僅僅在首頁返回了一句話“歡迎訪問我的博客”脏里。這只是個 hello world 級別的視圖她我。這一節(jié)里我們需要編寫真正的首頁視圖函數,當用戶訪問我們的博客首頁時迫横,他(她)將看到我們發(fā)表的博客文章列表番舆,就像演示項目里展示的這樣。
上一節(jié)我們闡明了 django 的開發(fā)流程矾踱。首先把 url 和相應的處理函數綁定恨狈,一般寫在 urls.py 文件里,然后在工程的 urls.py 文件引入呛讲。其次是編寫我們的視圖函數禾怠,視圖中需要渲染模板,我們也在 settings.py 中進行了模板相關的配置贝搁,讓 django 能夠找到需要渲染的模板吗氏。最后把渲染完成的 http 響應返回就可以了。相關的配置和準備工作都在上一節(jié)完成了雷逆,本節(jié)我們只需專心編寫視圖函數牲证,讓它實現我們想要的功能即可。
首頁的視圖函數其實很簡單关面,代碼像這樣:
from django.shortcuts import render
from .models import Post
def index(request):
post_list = Post.objects.all()
return render(request, 'blog/index.html', context={'post_list': post_list})
我們曾經在前面的章節(jié)講解過模型管理器 objects 的使用坦袍。這里我們使用 all() 方法從數據庫里獲取了全部的文章,存在了 post_list 變量里等太,然后如前一節(jié)所做捂齐,我們渲染了 blog/index.html 模板文件,并且把包含文章列表的 post_list 變量傳給了模板缩抡。
處理 css 與 js文件
我們的項目使用了從網上下載的一套博客模板(點擊這里下載全套模板)奠宜,這里面除了 html 文檔外,還包含了一些 css 文件和 js 文件以讓網頁呈現出我們現在看到的樣式瞻想。同樣我們需要對 django 做一些必要的配置压真,才能讓 django 知道如何在開發(fā)服務器中引入這些 css 和 js 文件,這樣才能讓博客頁面的 css 樣式生效蘑险。
按照慣例滴肿,我們把 css 和 js 文件放在 blog 應用的 static 文件夾下。因此佃迄,先在 blog 應用下建立一個 static 文件夾泼差。同時贵少,為了避免和其它 app 中的 css 和 js 文件命名沖突,我們再在 static 文件夾下建立一個 blog 文件夾堆缘,把下載的文件中的 css 和 js 文件夾連同里面的文件一同拷貝進這個目錄滔灶。最終我們的 blog 應用目錄結構變成了這樣:
blog/
__init__.py
static/
blog/
css/
.css 文件...
js/
.js 文件...
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
用模板中的 index.html 文件替換掉上一節(jié)我們自己寫的 index.html 文件。如果你好奇吼肥,現在就可以運行開發(fā)服務器录平,看看現在的首頁是什么樣子了。
你會看到首頁顯示的樣式非匙褐澹混亂萄涯,原因是 css 樣式文件沒有正確加載。需要以 django 的方式來正確地加載 css 和 js 文件唆鸡。css 樣式文件通常在 html 文檔的 head 標簽里引入涝影,打開 index.html 文件,在文件的開始處找到 head 標簽包裹的內容争占,大概像這樣:
<head>
<title>Black & White</title>
<!-- meta -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- css -->
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" >
<link rel="stylesheet" href="css/pace.css">
<link rel="stylesheet" href="css/custom.css">
<!-- js -->
<script src="js/jquery-2.1.3.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/pace.min.js"></script>
<script src="js/modernizr.custom.js"></script>
</head>
css 樣式文件在 link 標簽的 href 屬性里燃逻,而 js 文件在 script 標簽的 src 屬性里”酆郏可以看到諸如 href="css/bootstrap.min.css" 或者 src="js/jquery-2.1.3.min.js" 這樣的引用伯襟,由于引用文件的路徑不對,所以引入失敗握童。我們需要把它們改成正確的路徑姆怪。把代碼改成下面樣子,正確地引入 static 文件下的 css 和 js 文件:
<head>
<title>Black & White</title>
<!-- meta -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
+ {% load staticfiles %}
<!-- css -->
- <link rel="stylesheet" href="css/bootstrap.min.css">
+ <link rel="stylesheet" href="{% static 'blog/css/bootstrap.min.css' %}">
<link rel="stylesheet" >
- <link rel="stylesheet" href="css/pace.css">
- <link rel="stylesheet" href="css/custom.css">
+ <link rel="stylesheet" href="{% static 'blog/css/pace.css' %}">
+ <link rel="stylesheet" href="{% static 'blog/css/custom.css' %}">
<!-- js -->
- <script src="js/jquery-2.1.3.min.js"></script>
- <script src="js/bootstrap.min.js"></script>
- <script src="js/pace.min.js"></script>
- <script src="js/modernizr.custom.js"></script>
+ <script src="{% static 'blog/js/jquery-2.1.3.min.js' %}"></script>
+ <script src="{% static 'blog/js/bootstrap.min.js' %}"></script>
+ <script src="{% static 'blog/js/pace.min.js' %}"></script>
+ <script src="{% static 'blog/js/modernizr.custom.js' %}"></script>
</head>
我們把引用路徑放在了一個奇怪的符號里澡绩,例如:href="{% static 'blog/css/bootstrap.min.css' %}"稽揭。用 {% %} 包裹起來的叫做模板標簽。我們前面說過用 {{ }} 包裹起來的叫做模板變量肥卡,其作用是在最終渲染的模板里顯示由視圖函數傳過來的變量的值溪掀。而這里我們使用的模板標簽的功能則類似于函數,例如這里的 static 模板標簽步鉴,它把跟在它后面的字符串 'css/bootstrap.min.css' 轉換成正確的文件引入路徑揪胃。這樣 css 和 js 文件才能被正確加載,樣式才能正常顯示氛琢。注意這里有一個標簽 <link rel="stylesheet" >
我們沒有使用模板標簽喊递,因為這里的引用的文件是一個外部文件,不是我們項目里 css 目錄下的文件阳似,因此無需使用模板標簽骚勘。
如果你開發(fā)服務器還沒關的話(關了就重新運行),刷新首頁障般,這次應該能看到期望的效果了给涕。但目前我們看到的只是模板中預先寫好的一些數據(還都是英語的...)融师,我們得讓它顯示我們從數據庫中獲取的數據。下面來稍微改造一下模板:
在模板 index.html 中你會找到一系列 article 標簽:
...
<article class="post post-1">
...
</article>
<article class="post post-2">
...
</article>
<article class="post post-3">
...
</article>
...
這里面包裹的內容就是顯示的文章數據了。我們前面在視圖函數 index 里給模板傳了一個 post_list 變量递览,它里面包含著從數據庫中取出的文章數據列表。就像 Python 一樣尼啡,我們可以在模板中循環(huán)這個列表蹋嵌,把文章一篇篇循環(huán)出來,然后一篇篇顯示文章的數據青自。要在模板中使用循環(huán)株依,需要使用到前面提到的模板標簽,這次使用 {% for %} 模板標簽延窜。刪掉多余的 article 標簽恋腕,只留下一個 article 標簽,然后寫下列代碼:
...
{% for post in post_list %}
<article class="post post-1">
...
</article>
{% empty %}
<div class="no-post">暫時還沒有發(fā)布的文章逆瑞!</div>
{% endfor %}
...
可以看到語法和 Python 的 for 循環(huán)類似荠藤,只是被 {% %} 這樣一個模板標簽符號包裹著。{% empty %} 的作用是當 post_list 為空获高,即數據庫里沒有文章時顯示 {% empty %} 下面的內容哈肖,最后我們用 {% endfor %} 告訴 django 循環(huán)在這里結束了。
現在我們可以在循環(huán)體內通過 post 變量訪問單篇文章了念秧。分析 article 標簽里面的 html 內容淤井,h1 顯示的是文章的標題,
<h1 class="entry-title">
<a href="single.html">Adaptive Vs. Responsive Layouts And Optimal Text Readability</a>
</h1>
我們把標題替換成 post 中的數據
<h1 class="entry-title">
<a href="single.html">{{ post.title }}</a>
</h1>
這里 post 是 Post 類的一個實例摊趾,通過引用它的 title 屬性獲取 title 的值币狠。注意要把它包裹在模板變量里,因為它最終要被替換成實際的 title 值砾层。
<div class="entry-meta">
<span class="post-category"><a href="#">Web Design</a></span>
<span class="post-date"><a href="#"><time class="entry-date"
datetime="2012-11-09T23:15:57+00:00">February 2, 2013</time></a></span>
<span class="post-author"><a href="#">Albert Einstein</a></span>
<span class="comments-link"><a href="#">4 Comments</a></span>
</div>
這 4 個 span 標簽里分別顯示了 分類(category)总寻、文章發(fā)布時間、文章作者梢为、評論數渐行。再次替換掉一些數據,由于評論數暫時沒法替換铸董,因此先留著祟印,我們在實現了評論功能后再來修改它:
<div class="entry-meta">
<span class="post-category">
<a href="#">{{ post.category.name }} </a>
</span>
<span class="post-date">
<a href="#">
<time class="entry-date" datetime="{{ post.created_time }}">{{ post.created_time }} </time>
</a>
</span>
<span class="post-author"><a href="#">{{ post.author }} </a></span>
<span class="comments-link"><a href="#">4 Comments</a></span>
</div>
<div class="entry-content clearfix">
<p>...</p>
<div class="read-more cl-effect-14">
<a href="#" class="more-link">Continue reading <span class="meta-nav">→</span></a>
</div>
</div>
這里 p 標簽里顯示的是摘要,替換成 post 的摘要粟害,另外 Continue reading 表示繼續(xù)閱讀蕴忆,漢化一下:
<div class="entry-content clearfix">
<p>{{ post.excerpt }}</p>
<div class="read-more cl-effect-14">
<a href="#" class="more-link">繼續(xù)閱讀 <span class="meta-nav">→</span></a>
</div>
</div>
再次訪問首頁,它顯示:暫時還沒有發(fā)布的文章悲幅!好吧套鹅,做了這么多工作站蝠,但是數據庫中其實還沒有任何數據呀。下一節(jié)我們就實際寫幾篇文章保存到數據庫里卓鹿,看看顯示的效果究竟如何菱魔。