博客的文章類型一般不止一種:有時候你會寫高深莫測的技術文章,有時候又純粹只記錄一下當天的心情。html
所以對文章的分類就顯得至關的重要了,既方便博主對文章進行分類歸檔,也方便用戶有針對性的閱讀。python
而文章分類一個重要的途徑就是設置欄目。git
實現文章欄目功能的方法有多種。你能夠只是簡單的在文章的Model中增長CharField()
字段,以字符串的形式將欄目名稱保存起來(實際上這種實現更像是**「標籤」**,之後會講到)。這樣作的優勢是比較簡單;缺點也很明顯,就是時間長了你可能會記混欄目的名字,而且也不方便對欄目的其餘屬性進行擴展。github
所以對文章欄目能夠獨立爲一個Model,用外鍵與文章的Model關聯起來。django
修改article/modles.py
文件:函數
article/models.py
...
class ArticleColumn(models.Model):
""" 欄目的 Model """
# 欄目標題
title = models.CharField(max_length=100, blank=True)
# 建立時間
created = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
class ArticlePost(models.Model):
...
# 文章欄目的 「一對多」 外鍵
column = models.ForeignKey(
ArticleColumn,
null=True,
blank=True,
on_delete=models.CASCADE,
related_name='article'
)
...
複製代碼
欄目的Model有兩個字段,「名稱」和「建立日期」。post
一篇文章只有一個欄目,而一個欄目能夠對應多篇文章,所以創建「一對多」的關係。測試
寫好模型後記得用makemigrations
和migrate
指令遷移數據。網站
模型寫好以後就須要幾條欄目的數據來進行測試。因爲尚未寫視圖,所以須要善加利用Django自帶的後臺。url
首先把欄目模型註冊到後臺:
article/admin.py
...
from .models import ArticleColumn
# 註冊文章欄目
admin.site.register(ArticleColumn)
複製代碼
而後就能夠在後臺中添加欄目的數據條目了:
先隨便添加了「HTML」、「Java」、「Django」這3條。
在後臺中隨便打開一篇文章,「欄目」字段已經靜靜的在等你了:
隨機找幾篇文章設置不一樣的欄目用於測試。
以前咱們用卡片類型的UI界面展現文章列表。
卡片的好處是簡潔大方,可是隨着數據的增多,卡片小小的版面已經不堪重負了。
所以這裏重寫list.html
模板的列表循環:
article/list.html
...
<!-- 列表循環 -->
<div class="row mt-2">
{% for article in articles %}
<!-- 文章內容 -->
<div class="col-12">
<!-- 欄目 -->
{% if article.column %}
<button type="button" class="btn btn-sm mb-2 {% if article.column.title == 'Django' %} btn-success {% elif article.column.title == 'Java' %} btn-danger {% elif article.column.title == 'HTML' %} btn-warning {% endif %} " >
{{ article.column }}
</button>
{% endif %}
<!-- 標題 -->
<h4>
<b>
<a href="{% url 'article:article_detail' article.id %}" style="color: black;" >
{{ article.title }}
</a>
</b>
</h4>
<!-- 摘要 -->
<div>
<p style="color: gray;">
{{ article.body|slice:'100' }}...
</p>
</div>
<!-- 註腳 -->
<p>
<!-- 附加信息 -->
<span style="color: green;">
{{ article.total_views }} 瀏覽
</span>
<span style="color: blue;">
{{ article.created|date:'Y-m-d' }} 發佈
</span>
<span style="color: darkred;">
{{ article.updated|date:'Y-m-d' }} 更新
</span>
</p>
<hr>
</div>
{% endfor %}
</div>
...
複製代碼
最主要的改動就是新增了展示「欄目」的按鈕。咱們甚至還爲不一樣的欄目設置了不一樣的按鈕顏色。
在附加信息中順便還把以前沒有用到的日期信息也添加上去了。
來看看效果:
感受還不錯!
展現已經沒問題了,可是發表新文章時還不能選擇欄目。
修改寫文章的模板,在表單中新增下面的內容:
templates/article/create.html
...
<!-- 提交文章的表單 -->
<form method="post" action=".">
{% csrf_token %}
<!-- 文章標題 -->
...
<!-- 文章欄目 -->
<div class="form-group">
<label for="column">欄目</label>
<select class="form-control" id="column" name="column" >
<option value="none">請選擇欄目..</option>
{% for column in columns %}
<option value="{{ column.id }}">{{ column }}</option>
{% endfor %}
</select>
</div>
<!-- 文章正文 -->
...
<!-- 提交按鈕 -->
...
</form>
複製代碼
<select>
是表單的下拉框選擇組件。在這個組件中循環列出全部的欄目數據,而且設置value
屬性,指定表單提交欄目的id
值。
刷新頁面,效果像下面這樣:
跟以前同樣,可以展現了,可是尚未處理表單的視圖邏輯。
修改已有的寫文章視圖article_create()
,讓其可以處理表單上傳的欄目數據:
article/views.py
# 引入欄目Model
from .models import ArticleColumn
...
# 寫文章的視圖
...
def article_create(request):
if request.method == "POST":
...
if article_post_form.is_valid():
...
# 新增的代碼
if request.POST['column'] != 'none':
new_article.column = ArticleColumn.objects.get(id=request.POST['column'])
# 已有代碼
new_article.save()
...
else:
...
# 新增及修改的代碼
columns = ArticleColumn.objects.all()
context = { 'article_post_form': article_post_form, 'columns': columns }
...
複製代碼
新增代碼涉及get
和post
兩部分:
if
語句判斷該文章是否有欄目,若是有,則根據表單提交的value
值,關聯對應的欄目。測試一下,寫文章的欄目功能應該能夠正常工做了。
更新文章的視圖一樣也須要升級一下。
仍是先更改模板:
templates/article/update.html
...
<!-- 提交文章的表單 -->
<form method="post" action=".">
{% csrf_token %}
<!-- 文章標題 -->
...
<!-- 文章欄目 -->
<div class="form-group">
<label for="column">欄目</label>
<select class="form-control" id="column" name="column" >
<option value="none">請選擇欄目..</option>
{% for column in columns %}
<option value="{{ column.id }}" {% if column.id == article.column.id %} selected {% endif %} >
{{ column }}
</option>
{% endfor %}
</select>
</div>
<!-- 文章正文 -->
...
<!-- 提交按鈕 -->
...
</form>
...
複製代碼
與前面稍有不一樣的是,表單中判斷了column.id
與article.column.id
是否相等,若是相等則將其設置爲默認值。
而後修改視圖函數:
article/views.py
# 更新文章
...
def article_update(request, id):
...
# 判斷用戶是否爲 POST 提交表單數據
if request.method == "POST":
...
if article_post_form.is_valid():
...
# 新增的代碼
if request.POST['column'] != 'none':
article.column = ArticleColumn.objects.get(id=request.POST['column'])
else:
article.column = None
...
else:
...
# 新增及修改的代碼
columns = ArticleColumn.objects.all()
context = {
'article': article,
'article_post_form': article_post_form,
'columns': columns,
}
...
複製代碼
代碼邏輯與前面很相似。修改文章的欄目功能,也就完成了。
本章實現了簡單的欄目功能,能夠舒舒服服對文章進行分類了,強迫症福音啊。
還有些能夠完善的工做,好比:
單擊欄目按鈕顯示全部相同欄目的文章。這個功能與以前學過的最熱文章排序以及搜索文章很是的相似。還記得filter()
方法嗎?
欄目Model的增刪改查。
對我的博客來講,欄目數據的變更一般是不多的。若是你不想寫增刪改查,用後臺修改數據是徹底能夠的。
以上內容就再也不贅述了。留給讀者去嘗試實現。