基于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 命令行非阻塞输入的小例子
Sep 27 Python
简单理解Python中的装饰器
Jul 31 Python
Python极简代码实现杨辉三角示例代码
Nov 15 Python
Python+树莓派+YOLO打造一款人工智能照相机
Jan 02 Python
python3 selenium 切换窗口的几种方法小结
May 21 Python
使用Django启动命令行及执行脚本的方法
May 29 Python
python设定并获取socket超时时间的方法
Jan 12 Python
使用python绘制二元函数图像的实例
Feb 12 Python
Python人脸识别第三方库face_recognition接口说明文档
May 03 Python
pandas数值排序的实现实例
Jul 25 Python
Python实现老照片修复之上色小技巧
Oct 16 Python
Python实现GIF动图以及视频卡通化详解
Dec 06 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
Joomla使用Apache重写模式的方法
2016/05/04 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
2017/12/21 PHP
基于jQuery的固定表格头部的代码(IE6,7,8测试通过)
2010/05/18 Javascript
validator验证控件使用代码
2010/11/23 Javascript
vue指令以及dom操作详解
2017/03/04 Javascript
AngularJS中的promise用法分析
2017/05/19 Javascript
深入浅析JavaScript中的RegExp对象
2017/09/18 Javascript
JavaScript定义函数的三种实现方法
2017/09/23 Javascript
浅析JS抽象工厂模式
2017/12/14 Javascript
快速解决处理后台返回json数据格式的问题
2018/08/07 Javascript
vue 组件的封装之基于axios的ajax请求方法
2018/08/11 Javascript
vuex直接赋值的三种方法总结
2018/09/16 Javascript
vue项目中跳转到外部链接的实例讲解
2018/09/20 Javascript
小程序实现五星点评效果
2018/11/03 Javascript
小程序登录之支付宝授权的实现示例
2019/12/13 Javascript
Python的ORM框架SQLObject入门实例
2014/04/28 Python
Python爬虫实现爬取京东手机页面的图片(实例代码)
2017/11/30 Python
Python将图片转换为字符画的方法
2020/06/16 Python
python 请求服务器的实现代码(http请求和https请求)
2018/05/25 Python
Python对切片命名的实现方法
2018/10/16 Python
ActiveMQ:使用Python访问ActiveMQ的方法
2019/01/30 Python
Python3.5字符串常用操作实例详解
2019/05/01 Python
python函数调用,循环,列表复制实例
2020/05/03 Python
keras中模型训练class_weight,sample_weight区别说明
2020/05/23 Python
详解如何在css中引入自定义字体(font-face)
2018/05/17 HTML / CSS
日本亚马逊官方网站:Amazon.co.jp
2020/04/14 全球购物
软件测试面试题
2014/01/05 面试题
建筑个人求职信范文
2014/01/25 职场文书
小区门卫管理制度
2014/01/29 职场文书
纠风工作实施方案
2014/03/15 职场文书
《画家乡》教学反思
2014/04/22 职场文书
青春无悔演讲稿
2014/05/08 职场文书
寻找成龙观后感
2015/06/12 职场文书
教育教学读书笔记
2015/07/02 职场文书
Python包argparse模块常用方法
2021/06/04 Python
Sql Server 行数据的某列值想作为字段列显示的方法
2022/04/20 SQL Server