有了瀏覽量以後,文章受歡迎的程度就有了評價標準。隨之而來的就有根據瀏覽量對文章進行排序的需求,即顯示「最熱文章」。html
如今你已經很熟悉MTV模式,不須要我囉嗦也能完成任務:python
article_list_by_views()
,取出按瀏覽排序後的文章對象很簡單,但也隱藏着問題:最熱文章列表和以前的普通文章列表相比,大部分功能其實都是相同的,僅僅是排序不一樣而已。git
萬一哪天須要根據文章標題排序呢?萬一還須要用戶id排序、標籤排序、收藏排序...不只如此,就連路由urls.py
都要跟着膨脹。代碼會愈來愈臃腫且不可維護。github
重複的代碼是萬惡之源。所以這裏挑戰一下,不建立新的視圖/路由,而是將排序功能融合到已有的視圖/路由中。django
根據以上需求,重寫article_list()
:編程
article/views.py ... # 重寫文章列表 def article_list(request): # 根據GET請求中查詢條件 # 返回不一樣排序的對象數組 if request.GET.get('order') == 'total_views': article_list = ArticlePost.objects.all().order_by('-total_views') order = 'total_views' else: article_list = ArticlePost.objects.all() order = 'normal' paginator = Paginator(article_list, 3) page = request.GET.get('page') articles = paginator.get_page(page) # 修改此行 context = { 'articles': articles, 'order': order } return render(request, 'article/list.html', context)
重點知識以下:數組
?a=1&b=2
,參數間用&
隔開order
的值,判斷取出的文章如何排序order_by()
方法指定對象如何進行排序。模型中有total_views
這個整數字段,所以‘total_views’爲正序,‘-total_views’爲逆序order
也傳遞到模板中?由於文章須要翻頁!order
給模板一個標識,提醒模板下一頁應該如何排序這樣一來,排序所須要的參數均可以經過查詢得到,連urls.py
都不用改寫了。服務器
接下來修改文章列表模板:優化入口,而且正確分頁:函數
templates/article/list.html ... <div class="container"> <nav aria-label="breadcrumb"> <ol class="breadcrumb"> <li class="breadcrumb-item"> <a href="{% url 'article:article_list' %}"> 最新 </a> </li> <li class="breadcrumb-item"> <a href="{% url 'article:article_list' %}?order=total_views"> 最熱 </a> </li> </ol> </nav> <div class="row mt-2"> {% for article in articles %} ... {% endfor %} </div> <!-- 頁碼導航 --> ... <a href="?page=1&order={{ order }}" class="btn btn-success">« 1</a> ... <a href="?page={{ articles.previous_page_number }}&order={{ order }}" class="btn btn-secondary">...</a> ... {% if articles.has_next %} <a href="?page={{ articles.next_page_number }}&order={{ order }}" class="btn btn-secondary">{{ articles.next_page_number }}</a> ... <a href="?page={{ articles.paginator.num_pages }}&order={{ order }}" class="btn btn-success">{{ articles.paginator.num_pages }} »</a> ...
breadcrumb
order
參數啓動服務器,點擊「最熱」:測試
工做得很好!切換頁碼,留意地址欄中是如何變化的。
還剩一個小瑕疵:用戶點擊「最熱」按鈕後,此按鈕最好可以變爲灰色,而且不可點擊。這個精益求精的機會就留給讀者去優化吧。
header.html中有一個小改動:"寫文章"的入口被挪到用戶下拉菜單中了。
本章已經摸到一個高級的編程領域門檻了:代碼複用。將相似功能的代碼合併到了一塊兒,而且讓後續的功能擴展變得很容易。只須要在視圖中寫幾個elif
語句就搞定了。
在讀者之後的編程中,也要儘可能優化代碼結構,達到事半功倍的效果。
至此,博客雖小,功能卻至關完整了。繼續努力!
轉載請註明出處。