基于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数据库操作常用功能使用详解(创建表/插入数据/获取数据)
Dec 06 Python
Python新手实现2048小游戏
Mar 31 Python
python中__slots__用法实例
Jun 04 Python
python的random模块及加权随机算法的python实现方法
Jan 04 Python
TensorFlow打印tensor值的实现方法
Jul 27 Python
Python实现数据可视化看如何监控你的爬虫状态【推荐】
Aug 10 Python
浅谈Python在pycharm中的调试(debug)
Nov 29 Python
Django中更改默认数据库为mysql的方法示例
Dec 05 Python
python使用原始套接字发送二层包(链路层帧)的方法
Jul 22 Python
Django Rest framework认证组件详细用法
Jul 25 Python
详解如何用python实现一个简单下载器的服务端和客户端
Oct 28 Python
Python实现钉钉订阅消息功能
Jan 14 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
探讨:web上存漏洞及原理分析、防范方法
2013/06/29 PHP
yii中widget的用法
2014/12/03 PHP
flash javascript之间的通讯方法小结
2008/12/20 Javascript
15个款优秀的 jQuery 图片特效插件推荐
2011/11/21 Javascript
JS注册/移除事件处理程序(ExtJS应用程序设计实战)
2013/05/07 Javascript
jquery增加时编辑jqGrid(实例代码)
2013/11/08 Javascript
JavaScript检测弹出窗口是否已经关闭的方法
2015/03/24 Javascript
AngularJS中的DOM操作用法分析
2016/11/04 Javascript
Bootstrap输入框组件使用详解
2017/06/09 Javascript
AngularJS+Bootstrap3多级导航菜单的实现代码
2017/08/16 Javascript
React-Router如何进行页面权限管理的方法
2017/12/06 Javascript
使用Angular CLI进行Build(构建)和Serve详解
2018/03/24 Javascript
JS异步执行结果获取的3种解决方式
2019/02/19 Javascript
详解Nodejs get获取远程服务器接口数据
2019/03/26 NodeJs
Node 搭建一个静态资源服务器的实现
2019/05/20 Javascript
关于ckeditor在bootstrap中modal中弹框无法输入的解决方法
2019/09/11 Javascript
解决vue里a标签值解析变量,跳转页面,前面加默认域名端口的问题
2020/07/22 Javascript
Python Trie树实现字典排序
2014/03/28 Python
Django自定义分页效果
2017/06/27 Python
Python调用系统底层API播放wav文件的方法
2017/08/11 Python
使用django-crontab实现定时任务的示例
2018/02/26 Python
对pandas replace函数的使用方法小结
2018/05/18 Python
Python编程快速上手——选择性拷贝操作案例分析
2020/02/28 Python
Python Switch Case三种实现方法代码实例
2020/06/18 Python
CSS3中媒体查询结合rem布局适配手机屏幕
2019/06/10 HTML / CSS
美国伴娘礼服商店:Evening Collective
2019/10/07 全球购物
本科生职业生涯规划书范文
2014/01/21 职场文书
悬崖上的金鱼姬观后感
2015/06/15 职场文书
2016高校自主招生自荐信范文
2016/01/28 职场文书
2016年教代会开幕词
2016/03/04 职场文书
选择比努力更重要?这是长期以来对“努力”的最大误解
2019/07/12 职场文书
Python中的 Set 与 dict
2022/03/13 Python
如何通过一篇文章了解Python中的生成器
2022/04/02 Python
python实现简单的三子棋游戏
2022/04/28 Python
在windows server 2012 r2中安装mysql的详细步骤
2022/07/23 Servers