作者: HelloGitHub - 追梦人物 https://www.zmrenwu.com/
文中所涉及的示例代码, 已同步更新到 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, 从而达到粗略统计阅读量的目的.
『讲解开源项目系列』-- 让对开源项目感兴趣的人不再畏惧, 让开源项目的发起者不再孤单. 跟着我们的文章, 你会发现编程的乐趣, 使用和发现参与开源项目如此简单. 欢迎留言联系我们, 加入我们, 让更多人爱上开源, 贡献开源~
来源: https://www.cnblogs.com/xueweihan/p/11693206.html