基于Django统计博客文章阅读量


Posted in Python onOctober 29, 2019

如何精确地记录一篇文章的阅读量是一个比较复杂的问题,不过对于我们的博客来说,没有必要记录的那么精确。因此我们使用一种简单但有效的方式来记录博客文章的阅读量:文章每被浏览一次,则其阅读量 +1,即所谓的文章页面 PV(Page View)数。虽然简单粗暴,但却高效实用。

增加新字段

为了记录文章的浏览量,需要在文章的数据库表中新增一个用于存储阅读量的字段。因此给博客文章的模型新增一个 views 字段:

blog/models.py

class Post(models.Model):
  # ... 其它已有字段
  # 新增 views 字段记录阅读量
  views = models.PositiveIntegerField(default=0, editable=False)

注意 views 字段的类型为 PositiveIntegerField,该类型的值只允许为正整数或 0,因为阅读量不可能为负值。初始化时 views 的值为 0。将 editable 参数设为 False 将不允许通过 django admin 后台编辑此字段的内容。因为阅读量应该根据被访问次数统计,而不应该人为修改。

增加模型方法

一旦用户访问了某篇文章,这时就应该将 views 的值 +1,这个过程最好由 Post 模型自己来完成,因此再给模型添加一个自定义的方法:

blog/models.py

class Post(models.Model):
  # ... 其它已有字段
  # 新增 views 字段记录阅读量
  views = models.PositiveIntegerField(default=0)  
  # ... 其它已有的模型方法
  def increase_views(self):
    self.views += 1
    self.save(update_fields=['views'])

increase_views 方法首先将自身对应的 views 字段的值 +1(此时数据库中的值还没变),然后调用 save 方法将更改后的值保存到数据库。注意这里使用了 update_fields 参数来告诉 Django 只更新数据库中 views 字段的值,以提高效率。

你也许担心如果两个人同时访问一篇文章,更改数据库中的阅读量字段的值时会不会冲突?其实不必担心,我们本来就不是精确地统计阅读量,而且个人博客的流量通常也不会很大,所以偶尔的冲突导致的数据误差是可以忽略不计的。

迁移数据库

一旦更改了模型,就需要迁移数据库,以便让 Django 将更改反应到数据库中。在项目根目录运行如下两条命令:

$ pipenv run python manage.py makemigrations
$ pipenv run python manage.py migrate

关于数据库的迁移,具体可以参考 Django 迁移、操作数据库。

修改视图函数

当用户请求访问某篇文章时,处理该请求的视图函数为 detail 。一旦该视图函数被调用,说明文章被访问了一次,因此我们修改 detail 视图函数,让被访问的文章在视图函数被调用时阅读量 +1。

blog/views.py

def detail(request, pk):
  post = get_object_or_404(Post, pk=pk)
  
  # 阅读量 +1
  post.increase_views()

  md = markdown.Markdown(extensions=[
    'markdown.extensions.extra',
    'markdown.extensions.codehilite',
    # 记得在顶部引入 TocExtension 和 slugify
    TocExtension(slugify=slugify),
  ])
  post.body = md.convert(post.body)

  m = re.search(r'<div class="toc">\s*<ul>(.*)</ul>\s*</div>', md.toc, re.S)
  post.toc = m.group(1) if m is not None else ''

  return render(request, 'blog/detail.html', context={'post': post})

即只需在视图函数中调用模型的 increase_views 方法即可。

在模板中显示阅读量

在模板中显示阅读量和显示其它字段一样,只需要使用模板变量即可。即模板适当的地方使用 {{ post.views }} 模板变量。这里我们分别修改两个地方,分别是 index.html 和 detail.html。

templates/blog/index.html

<div class="entry-meta">
 ...
 <span class="views-count"><a href="{{ post.get_absolute_url }}" rel="external nofollow" >{{ post.views }} 阅读</a></span>
</div>

templates/blog/detail.html

<div class="entry-meta">
 ...
 <span class="views-count"><a href="#" rel="external nofollow" >{{ post.views }} 阅读</a></span>
</div>

好了,这样当用户每访问一次文章详情,views 记录的数值就会 +1,从而达到粗略统计阅读量的目的。

示例代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python使用代理抓取网站图片(多线程)
Mar 14 Python
在Python的web框架中编写创建日志的程序的教程
Apr 30 Python
Python简单实现子网掩码转换的方法
Apr 13 Python
一个Python最简单的接口自动化框架
Jan 02 Python
python使用PIL给图片添加文字生成海报示例
Aug 17 Python
Python实现提取XML内容并保存到Excel中的方法
Sep 01 Python
对python cv2批量灰度图片并保存的实例讲解
Nov 09 Python
对python pandas 画移动平均线的方法详解
Nov 28 Python
python验证身份证信息实例代码
May 06 Python
Python numpy线性代数用法实例解析
Nov 15 Python
Python 爬虫性能相关总结
Aug 03 Python
用Python实现屏幕截图详解
Jan 22 Python
pygame实现俄罗斯方块游戏(基础篇3)
Oct 29 #Python
python安装gdal的两种方法
Oct 29 #Python
pygame实现俄罗斯方块游戏(基础篇2)
Oct 29 #Python
pygame实现俄罗斯方块游戏(基础篇1)
Oct 29 #Python
pygame实现五子棋游戏
Oct 29 #Python
python多线程案例之多任务copy文件完整实例
Oct 29 #Python
jenkins配置python脚本定时任务过程图解
Oct 29 #Python
You might like
PHP的FTP学习(四)
2006/10/09 PHP
php随机输出名人名言的代码
2012/10/07 PHP
解析isset与is_null的区别
2013/08/09 PHP
JavaScript经典效果集锦
2010/07/06 Javascript
jQuery validate 中文API 附validate.js中文api手册
2010/07/31 Javascript
jquery实现的省市区三级联动
2015/04/02 Javascript
JavaScript框架是什么?怎样才能叫做框架?
2015/07/01 Javascript
在JavaScript的jQuery库中操作AJAX的方法讲解
2015/08/15 Javascript
js实现随屏幕滚动的带缓冲效果的右下角广告代码
2015/09/04 Javascript
js解决movebox移动问题
2016/03/29 Javascript
JS+HTML5手机开发之滚动和惯性缓动实现方法分析
2016/06/12 Javascript
JavaScript中日期函数的相关操作知识
2016/08/03 Javascript
vue 和vue-touch 实现移动端左右导航效果(仿京东移动站导航)
2017/04/22 Javascript
利用JS如何计算字符串所占字节数示例代码
2017/09/13 Javascript
Node.js中的cluster模块深入解读
2018/06/11 Javascript
js限制input只能输入有效的数字(第一个不能是小数点)
2018/09/28 Javascript
JavaScript多种页面刷新方法小结
2019/04/04 Javascript
python回溯法实现数组全排列输出实例分析
2015/03/17 Python
Django中模版的子目录与include标签的使用方法
2015/07/16 Python
python DataFrame获取行数、列数、索引及第几行第几列的值方法
2018/04/08 Python
python版本五子棋的实现代码
2018/12/11 Python
Python json模块与jsonpath模块区别详解
2020/03/05 Python
python安装第三方库如xlrd的方法
2020/10/31 Python
详解Selenium 元素定位和WebDriver常用方法
2020/12/04 Python
几个Shell Script面试题
2012/08/31 面试题
网吧消防安全制度
2014/01/28 职场文书
保险专业大学生职业规划书
2014/03/03 职场文书
领导干部整治奢华浪费之风思想汇报
2014/10/07 职场文书
党员干部反四风民主生活会对照检查材料思想汇报
2014/10/12 职场文书
师德师风个人整改措施
2014/10/27 职场文书
2014年会计人员工作总结
2014/12/10 职场文书
2015年推普周活动总结
2015/03/27 职场文书
狂人日记读书笔记
2015/06/30 职场文书
党员干部学习十八届五中全会精神心得体会
2016/01/05 职场文书
创业计划书之家教中心
2019/09/25 职场文书
Python使用sql语句对mysql数据库多条件模糊查询的思路详解
2021/04/12 Python