基于Django统计博客文章阅读量
如何精确地记录一篇文章的阅读量是一个比较复杂的问题,不过对于我们的博客来说,没有必要记录的那么精确。因此我们使用一种简单但有效的方式来记录博客文章的阅读量:文章每被浏览一次,则其阅读量+1,即所谓的文章页面PV(PageView)数。虽然简单粗暴,但却高效实用。
增加新字段
为了记录文章的浏览量,需要在文章的数据库表中新增一个用于存储阅读量的字段。因此给博客文章的模型新增一个views字段:
blog/models.py
classPost(models.Model): #...其它已有字段 #新增views字段记录阅读量 views=models.PositiveIntegerField(default=0,editable=False)
注意views字段的类型为PositiveIntegerField,该类型的值只允许为正整数或0,因为阅读量不可能为负值。初始化时views的值为0。将editable参数设为False将不允许通过djangoadmin后台编辑此字段的内容。因为阅读量应该根据被访问次数统计,而不应该人为修改。
增加模型方法
一旦用户访问了某篇文章,这时就应该将views的值+1,这个过程最好由Post模型自己来完成,因此再给模型添加一个自定义的方法:
blog/models.py
classPost(models.Model): #...其它已有字段 #新增views字段记录阅读量 views=models.PositiveIntegerField(default=0) #...其它已有的模型方法 defincrease_views(self): self.views+=1 self.save(update_fields=['views'])
increase_views方法首先将自身对应的views字段的值+1(此时数据库中的值还没变),然后调用save方法将更改后的值保存到数据库。注意这里使用了update_fields参数来告诉Django只更新数据库中views字段的值,以提高效率。
你也许担心如果两个人同时访问一篇文章,更改数据库中的阅读量字段的值时会不会冲突?其实不必担心,我们本来就不是精确地统计阅读量,而且个人博客的流量通常也不会很大,所以偶尔的冲突导致的数据误差是可以忽略不计的。
迁移数据库
一旦更改了模型,就需要迁移数据库,以便让Django将更改反应到数据库中。在项目根目录运行如下两条命令:
$pipenvrunpythonmanage.pymakemigrations $pipenvrunpythonmanage.pymigrate
关于数据库的迁移,具体可以参考Django迁移、操作数据库。
修改视图函数
当用户请求访问某篇文章时,处理该请求的视图函数为detail。一旦该视图函数被调用,说明文章被访问了一次,因此我们修改detail视图函数,让被访问的文章在视图函数被调用时阅读量+1。
blog/views.py
defdetail(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'\s* (.*)
\s*
即只需在视图函数中调用模型的increase_views方法即可。
在模板中显示阅读量
在模板中显示阅读量和显示其它字段一样,只需要使用模板变量即可。即模板适当的地方使用{{post.views}}模板变量。这里我们分别修改两个地方,分别是index.html和detail.html。
templates/blog/index.html
... {{post.views}}阅读
templates/blog/detail.html
... {{post.views}}阅读