开发 Django 博客文章阅读量统计功能
文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库
如何精确地记录一篇文章的阅读量是一个比较复杂的问题,不过对于我们的博客来说,没有必要记录的那么精确。因此我们使用一种简单但有效的方式来记录博客文章的阅读量:文章每被浏览一次,则其阅读量 +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 }}">{{ post.views }} 阅读</a></span>
</div>
templates/blog/detail.html
<div class="entry-meta">
...
<span class="views-count"><a href="#">{{ post.views }} 阅读</a></span>
</div>
好了,这样当用户每访问一次文章详情,views
记录的数值就会 +1,从而达到粗略统计阅读量的目的。
『讲解开源项目系列』——让对开源项目感兴趣的人不再畏惧、让开源项目的发起者不再孤单。跟着我们的文章,你会发现编程的乐趣、使用和发现参与开源项目如此简单。欢迎留言联系我们、加入我们,让更多人爱上开源、贡献开源~
开发 Django 博客文章阅读量统计功能的更多相关文章
- 利用Github Pages创建的Jekyll模板个人博客添加阅读量统计功能
目录 前言 准备工作 模板文件修改 写在最后 内容转载自我自己的博客 @(文章目录) 前言 Jekyll 是一个简单的免费的 Blog 生成工具,类似 WordPress .它只是一个生成静态网页的工 ...
- 基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 为你的CSDN博客添加CNZZ流量统计功能
一.流量统计介绍 流量统计是指通过各种科学的方式,准确的纪录来访某一页面的访问者的流量信息,目前而言,必须具备可以统计. 1.简介 统计独立的访问者数量(独立用户.独立访客): 可以统计独立的IP地址 ...
- web开发-Django博客系统
项目界面图片预览 项目代码github地址 项目完整流程 项目流程: 1 搞清楚需求(产品经理) (1) 基于用户认证组件和Ajax实现登录验证(图片验证码) (2) 基于forms组件和Ajax实现 ...
- 搭建自己的博客(九):使用shell模式批量添加博客文章并增加分页功能
想做个博客分页功能,但是没有太多的文章.所以使用shell命令行创建多篇文章. 1.打开pycharm下的terminal终端 python manage.py shell # 打开python终端 ...
- WordPress文章阅读量统计和显示(非插件, 刷新页面不累加)
本文已同步到专业技术网站 www.sufaith.com, 该网站专注于前后端开发技术与经验分享, 包含Web开发.Nodejs.Python.Linux.IT资讯等板块. WordPress文章阅读 ...
- Django 博客开发教程目录索引
Django 博客开发教程目录索引 本项目适合 0 基础的 Django 开发新人. 项目演示地址:Black & White,代码 GitHub 仓库地址:zmrenwu/django-bl ...
- django博客项目8:文章详情页
首页展示的是所有文章的列表,当用户看到感兴趣的文章时,他点击文章的标题或者继续阅读的按钮,应该跳转到文章的详情页面来阅读文章的详细内容.现在让我们来开发博客的详情页面,有了前面的基础,开发流程都是一样 ...
- 使用IntelliJ IDEA开发SpringMVC网站(五)博客文章管理
原文:使用IntelliJ IDEA开发SpringMVC网站(五)博客文章管理 摘要 通过对博客文章的管理,实现外键操作. 目录[-] 八.博客文章管理 1.查看文章 2.添加博客 3 ...
随机推荐
- Optional和Stream的map与flatMap
Optional的map和flatMap Optional存在map和flatMap方法.map源码如下 public<U> Optional<U> map(Function& ...
- Flutter开发环境配置(MAC版)
一.配置镜像 打开命令终端,输入命令open ~/.bash_profile,打开bash_profile文本,添加镜像路径并保存 export PUB_HOSTED_URL=https://pub. ...
- DOM的预习
HTML DOM 将 HTML 文档视作树结构.这种结构被称为节点树: 一些常用的 HTML DOM 方法: getElementById(id) - 获取带有指定 id 的节点(元素) append ...
- 如何在spingboot项目中自定义自己的配置
在实际开发中,为了方便我们常常会考虑把配置文件的某一类配置映射到配置类上,方便spring容器加载,实现方法如下: 1. 书写配置文件信息:书写某一类特定字段开头的配置信息,例如在yml配置文件中可以 ...
- Java多线程(十四):Timer
Timer schedule(TimerTask task, Date time) 该方法在指定日期执行任务,如果是过去的时间,这个任务会立即被执行. 执行时间早于当前时间 示例代码,当前时间是201 ...
- 39 (OC) 瀑布流、不规则UI
39 (OC) 瀑布流.不规则UI
- 一个简单的jquery ajax表单提交 带数据校验 layer弹框提示
<input type="hidden" id="url" value="index.php"/> <form id=&q ...
- 修改zabbix的端口号
1.前言 zabbix-server的默认端口号是10051.如果存在端口号冲突,需要更改端口号. 以下为更改端口号的步骤. 2.更改配置文件 通常用安装包,也就是yum方式部署的话,其默认的配置文 ...
- NET Core 3.0 新姿势 将AutoFac替换内置DI
.NET Core 3.0 和 以往版本不同,替换AutoFac服务的方式有了一定的变化,在尝试着升级项目的时候出现了一些问题. 原来在NET Core 2.1时候,AutoFac返回一个 IServ ...
- 基于操作系统原理的Linux的内存管理
一.实验目的 1.理解虚拟内存.磁盘缓存的概念. 2.掌握基本的内存管理知识. 3.掌握查看实时查看内存.内存回收的方法 二.实验内容 1. 监控内存使用情况 2. 检查和回收内容 三.实验平台 1. ...