有了浏览量以后,文章受欢迎的程度就有了评价标准。随之而来的就有根据浏览量对文章进行排序的需求,即显示**“最热文章”**。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
语句就搞定了。
在读者之后的编程中,也要尽可能优化代码结构,达到事半功倍的效果。
至此,博客虽小,功能却至关完整了。继续努力!
转载请注明出处。