基于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 16 Python
Python实现高效求解素数代码实例
Jun 30 Python
python通过加号运算符操作列表的方法
Jul 28 Python
python anaconda 安装 环境变量 升级 以及特殊库安装的方法
Jun 21 Python
python 二分查找和快速排序实例详解
Oct 13 Python
python查看模块,对象的函数方法
Oct 16 Python
Python 访问限制 private public的详细介绍
Oct 16 Python
python爬取网易云音乐评论
Nov 16 Python
Python学习笔记基本数据结构之序列类型list tuple range用法分析
Jun 08 Python
TensorFlow tf.nn.max_pool实现池化操作方式
Jan 04 Python
python实现密码强度校验
Mar 18 Python
Python selenium模拟网页点击爬虫交管12123违章数据
May 26 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 4.2书写安全的脚本
2006/10/09 PHP
php防止伪造数据从地址栏URL提交的方法
2014/08/24 PHP
Apache PHP MySql安装配置图文教程
2016/08/27 PHP
PHP PDO和消息队列的个人理解与应用实例分析
2019/11/25 PHP
JavaScript延迟加载
2021/03/09 Javascript
特殊字符、常规符号及其代码对照表
2006/06/26 Javascript
js验证表单第二部分
2006/11/25 Javascript
11款基于Javascript的文件管理器
2009/10/25 Javascript
jquery获取焦点和失去焦点事件代码
2013/04/21 Javascript
jQuery+html5实现div弹出层并遮罩背景
2015/04/15 Javascript
JavaScript学习小结(一)——JavaScript入门基础
2015/09/02 Javascript
Bootstrap前端开发案例二
2016/06/17 Javascript
全面解析Bootstrap表单样式的使用
2016/09/09 Javascript
JavaScript调用模式与this关键字绑定的关系
2018/04/21 Javascript
Vue infinite update loop的问题解决
2019/04/23 Javascript
vue组件中watch props根据v-if动态判断并挂载DOM的问题
2019/05/12 Javascript
微信小程序与公众号实现数据互通的方法
2019/07/25 Javascript
[02:40]DOTA2英雄基础教程 炼金术士
2013/12/23 DOTA
[46:55]完美世界DOTA2联赛决赛 FTD vs Phoenix 第三场 11.08
2020/11/11 DOTA
python批量修改文件后缀示例代码分享
2013/12/24 Python
Python函数可变参数定义及其参数传递方式实例详解
2015/05/25 Python
Python正则表达式常用函数总结
2017/06/24 Python
Python设计模式之模板方法模式实例详解
2019/01/17 Python
python绘制彩虹图
2019/12/16 Python
将tensorflow.Variable中的某些元素取出组成一个新的矩阵示例
2020/01/04 Python
python实现在线翻译
2020/06/18 Python
python实现自动打卡的示例代码
2020/10/10 Python
印尼穆斯林时尚购物网站:Hijabenka
2016/12/10 全球购物
新西兰网上购物,折扣店:BestDeals.co.nz
2019/03/20 全球购物
日本化妆品植村秀俄罗斯官方网站:Shu Uemura俄罗斯
2020/02/01 全球购物
草船借箭教学反思
2014/02/03 职场文书
大学第二课堂活动总结
2014/07/08 职场文书
大专毕业生自我鉴定范文(2篇)
2014/09/27 职场文书
工程资料员岗位职责
2015/04/13 职场文书
雷锋电影观后感
2015/06/10 职场文书
小学生暑假安全保证书
2015/07/13 职场文书