V. 推荐新闻
在首页展示3篇点击量最高的文章
1>接口设计
- 接口说明:
类目 | 说明 |
---|---|
请求方法 | GET |
url定义 | / |
参数格式 | 无参数 |
2.返回内容
返回新闻页面,直接在模板渲染
2>后端代码
2.1>视图代码
# 修改news/views.py中的index视图
def index(request):
"""
新闻首页视图
url: /
:param request:
:return:
"""
tags = Tag.objects.only('id', 'name').filter(is_delete=False)
# 通过外键获取新闻的标题和图片,并按照点击量降序的方式, 抽取3篇最热门的文章
hot_news = HotNews.objects.only('news__title', 'news__image_url', 'news_id').filter(is_delete=False).order_by('priority', '-news__clicks')[:constants.SHOW_HOTNEWS_COUNT]
return render(request, 'news/index.html',
context={
'tags': tags,
'hot_news': hot_news
})
注意这一句:
hot_news = HotNews.objects.only('news__title', 'news__image_url', 'news_id').filter(is_delete=False).order_by('priority', '-news__clicks')[:constants.SHOW_HOTNEWS_COUNT]
由于使用了外键, 所以当该语句执行时, 实际的操作是:
SELECT `tb_hotnews`.`id`, `tb_hotnews`.`news_id` FROM `tb_hotnews` INNER JOIN `tb_news` ON (`tb_hotnews`.`news_id` = `tb_news`.`id`) WHERE `tb_hotnews`.`is_delete` = False ORDER BY `tb_hotnews`.`priority` ASC, `tb_news`.`update_time` ASC, `tb_news`.`id` ASC LIMIT 3
仅仅只读取了tb_hotnews
.id
和tb_hotnews
.news_id
, 这样就会导致我们在访问news
中的数据时, 又去数据库中查询了一次, 使得代码执行的时间成倍提升
为优化这一点, 需要使用select_related('news')
, 改成如下代码
hot_news = HotNews.objects.select_related('news').only('news__title', 'news__image_url', 'news_id').filter(is_delete=False).order_by('priority', '-news__clicks')[:constants.SHOW_HOTNEWS_COUNT]
实际的语句就变成了
SELECT `tb_hotnews`.`id`, `tb_hotnews`.`news_id`, `tb_news`.`id`, `tb_news`.`title`, `tb_news`.`image_url` FROM `tb_hotnews` INNER JOIN `tb_news` ON (`tb_hotnews`.`news_id` = `tb_news`.`id`) WHERE `tb_hotnews`.`is_delete` = False ORDER BY `tb_hotnews`.`priority` ASC, `tb_news`.`update_time` ASC, `tb_news`.`id` ASC LIMIT 3
一次性读取到我们所需的所有数据, Great !
select_related()
可以用在查询外键字段的时候, 主要作用是提升效率, 官方文档: select_related()
2.2>定义常量
# 在news/constants.py中定义下面的常量
# 显示热门新闻条数
SHOW_HOTNEWS_COUNT = 3
3>前端代码
3.1>html代码
<!-- 修改templates/news/index.html -->
<ul class="recommend-news">
{% for item in hot_news %}
<li>
<a href="https://www.shiguangkey.com/course/2432" target="_blank">
<div class="recommend-thumbnail">
<img src="{{ item.news.image_url }}" alt="title">
</div>
<p class="info">{{ item.news.title }}</p>
</a>
</li>
{% endfor %}
</ul>
<!-- recommend-news end -->
由于文章详情还没有完成, 所以这里就先暂时放着一个链接, 之后我们再回来补上