关于本站
1、基于Django+Bootstrap开发
2、主要发表本人的技术原创博客
3、本站于 2015-12-01 开始建站
在我的博客列表页面中,每页显示12篇博文。随着博文发表越来越多,很多文章自然而然地被藏在深处。
这样不利于展示我的博客内容。所以需要提高博文的曝光率。
提高博文的曝光率常见地方法是文章推荐。我准备开发两种:随机推荐和猜你喜欢。
随机推荐很好处理,而猜你喜欢需要分析用户行为。先看看随机推荐如何实现。
遵循先前端,再后端,最后反馈前端的开发流程。
为了SEO优化,就不采用ajax的方式获取随机推荐博文的文章列表。考虑直接输出到页面,而需要输出到页面的有两个地方:博客列表和博文文章。
刚好我这两个模版页面的父级页面都是同一个,修改该父级页面即可。打开该模版页面,修改如下代码:
{% extends "base.html" %} {% block title %}杨仕航的博客{% endblock %} {% block blog_active %}active{% endblock %} {% block extra_head %} <link rel="stylesheet" type="text/css" href="/static/css/global/blog.css"> {% block blog_head %}{% endblock %} {% endblock %} {% block content %} <div class="col-md-9 col-xs-12"> {% block blog_content%} {# 博文列表和博文文章 #} {% endblock %} </div> {#侧边栏#} <div class="col-md-3 col-xs-12 blog-border"> <div class="side-list"> <h4> <span class="glyphicon glyphicon-book"></span> 随机推荐 </h4> <ul> {% for blog in rand_blogs %} <li> <a href="{%url 'detailblog' blog.id%}" target="_blank"> {{blog.caption}} </a> </li> {% endfor %} </ul> </div> </div> {% endblock %}
其中,侧边栏部分的代码是我新增的。
我需要传递rand_blogs数据给该页面,再循环遍历输出。rand_blogs是随机博客的列表。
初步加上前端代码之后,再修改后端代码,产生随机博客列表。
添加该功能代码之后,还需要考虑一个问题:对于随机产生的博客列表中,怎么剔除当前博文。
若在博客列表页面,就无需剔除,因为当前没有打开某一篇文章。
若打开了某一篇文章,就需要剔除该篇文章。避免重复显示。
一开始,想到的方法是先随机获取10篇博文。判断这10篇博文是否有包含当前打开的文章。若包含,则剔除,再继续随机获取多一篇文章。而且还需要判断这篇文章是否为当前打开的文章,直到不等于当前打开的文章为止。
这种做法效率不高。后来脑筋一转,想到另外一个思路。
我可以先获取11篇博文。判断这11篇博文是否包含当前打开的文章,若包含,则剔除,还剩下10篇博文。若不包含,再取前10篇文章即可。
打开blog应用的views.py文件,添加引用:
#coding:utf-8 from apps_project.blog.models import Blog #博客对应的模型 import random #随机数模块
添加获取前10篇随机博文的方法:
def rand_blogs(except_id=0): #随机获取 10+1 rand_count = 10 blogs = random.sample(Blog.objects.all(), rand_count + 1) #去掉要排除的博文 blogs_id = map(lambda x:x.id, blogs) if blogs_id.count(except_id)>0: #移除排除的博文 blogs.pop(blogs_id.index(except_id)) #返回前10篇 return blogs[:rand_count]
响应博客列表的方法中,加上rand_blogs参数的返回数据:
#返回随机推荐的博文 (我这里用一个字典记录,再返回。根据自己的实际情况自行修改) data['rand_blogs'] = rand_blogs()
响应某篇博文的方法中,也
加上rand_blogs参数的返回数据:
#返回随机推荐的博文 (我这里用一个字典记录,再返回。根据自己的实际情况自行修改) #id是该方法获取到的当前打开文章的id,通过根据实际情况修改 data['rand_blogs'] = rand_blogs(id)
保存,运行可看到如下效果:
最后,再反馈前端。这里主要修改该侧边栏的样式即可。
多谢网友“杨学光”的建议。他建议随机排序的方法如下:
def rand_blogs(except_id=0): rand_count = 10 return Blog.objects.exclude(id=except_id).order_by('?')[:rand_count]
先用exclude排除当前打开博文,exclude相当于“不等于”条件。
再使用order_by('?')随机排序。这个方法我不知道,测试一下。发现确实可以这么处理。
最后才用切片器取前10条博客。
我在shell下测试,看到sql语句如下(select部分我用*代替全部字段):
SELECT "blog_blog".* FROM "blog_blog" WHERE NOT ("blog_blog"."id" = 1) ORDER BY RANDOM() ASC LIMIT 10;
其中,order_by('?')对应 order by random()。
我推荐杨学光这种方法。因为执行效率要比我上面的方法高,直接执行SQL语句一步到位。