一、前言
如果知道每篇文章的浏览量,管理员就可以了解到访问者对文章的喜好程度,方便后续推出相关内容文章,同时对热门博客的统计和阅读趋势图打好基础。针对阅读统计功能,前前后后我一共想到了三种方法,各种方法都有利有弊。
二、采用该模型字段计数
?1) 修改Post模型read_num。
2) 优化:设置cookie判断是否用户多次点击response.set_cookie()。
优点:简单。
缺点:1.后台编辑博客可能影响数据。
2.功能单一,无法统计某一天的阅读数量。
3) 具体实现:
在Post模型类中直接定义一个read_num的字段名。
read_num = models.IntegerField(default=0)
然后可以通过对Post属性read_num的操作来实现阅读计数+1的逻辑处理。
post.read_num += 1 ???post.save()
三、设计功能独立的ReadNum模型数据表
1) 添加read_num字段。
2) 增加post外键。
3) 利用ReadNum.objects.filter(post=post)来过滤当前的文章计数对象。
4) 优化:设置cookie判断是否用户多次点击response.set_cookie()。
在blog/models.py文件中,与定义Post类似,定义一个ReadNum的模型类。
class ReadNum(models.Model): ???read_num = models.IntegerField(u‘阅读次数‘, default=0) ???post = models.OneToOneField(Post, on_delete=models.CASCADE) ???def __str__(self): ???????return self.read_num ???class Meta: ???????verbose_name = ‘阅读‘ ???????verbose_name_plural = ‘阅读‘
通过objects的filter方法来过滤当前博客是否有阅读的记录,如不存在记录,则创建新的readnum计数对象。
if ReadNum.objects.filter(post=post).count(): ???# 存在记录 ???readnum = ReadNum.objects.get(post=post)else: ???# 不存在记录 ???readnum = ReadNum(post=post)readnum.read_num += 1readnum.save()
阅读计数表就算是建好了,还需要将阅读数量加到后台的每篇文章中,在Post模型类中添加该方法。
def get_read_num(self): ???try: ???????return self.readnum.read_num ???except exceptions.ObjectDoesNotExist: ???????return 0
将get_read_num方法添加到admin.py的list_display中
list_display = (‘id‘, ‘title‘, ‘created_time‘, ‘modified_time‘, ‘category‘, ‘author‘, ‘get_read_num‘)
四、设计功能独立的计数应用read_statistics
导入两个模块GenericForeignKey和ContentType(非常重要)。
from django.contrib.contenttypes.fields import GenericForeignKeyfrom django.contrib.contenttypes.models import ContentType
新增ReadNum模型表,创建read_num这个字段名。
from django.db import modelsfrom django.contrib.contenttypes.fields import GenericForeignKeyfrom django.contrib.contenttypes.models import ContentTypeclass ReadNum(models.Model): ???""" ???????单篇博客计数的模型类 ???????继承model.Model模型类 ???""" ???read_num = models.IntegerField(u‘阅读计数‘, default=0) ???content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) ???object_id = models.PositiveIntegerField() ???# 使用contenttypes模型类来找出关联blog ???content_object = GenericForeignKey(‘content_type‘, ‘object_id‘) ???class Meta: ???????verbose_name = ‘阅读计数‘ ???????verbose_name_plural = ‘阅读计数‘ ???????ordering = [‘-read_num‘]
新增utils.py作为工具包,加入阅读计数+1的逻辑处理。
ct = ContentType.objects.get_for_model(obj)key = "%s_%s_read" % (ct.model, obj.pk)if not request.COOKIES.get(key): ???‘‘‘ ???if ReadNum.objects.filter(content_type=ct, object_id=obj.pk).count(): ???????# 存在记录 ???????readnum = ReadNum.objects.get(content_type=ct, object_id=obj.pk) ???else: ???????# 不存在记录 ???????readnum = ReadNum(content_type=ct, object_id=obj.pk) ???‘‘‘ ???readnum, created = ReadNum.objects.get_or_create(content_type=ct, object_id=obj.pk) ???# 计数+1 ???readnum.read_num += 1 ???readnum.save()
解决后台计数对象没创建时的解决办法,新增一个ReadNumExpandMethod类。
class ReadNumExpandMethod(object): ???""" ???????计数扩展类,此方法放在admin的list_display中 ???????继承object模型类 ???""" ???def get_read_num(self): ???????ct = ContentType.objects.get_for_model(self) ???????# 此处的一个异常处理,用来捕获没有计数对象的情况 ???????# 例如在admin后台中,没有计数值会显示为‘-’ ???????try: ???????????readnum = ReadNum.objects.get(content_type=ct, object_id=self.pk) ???????????return readnum.read_num ???????# 对象不存在就返回0 ???????except exceptions.ObjectDoesNotExist: ???????????return 0
然后让blog/models中的Post模型类继承ReadNumExpandMethod类中的方法。
class Post(models.Model, ReadNumExpandMethod): ?????...
将方法加入到blog/amdin.py中的list_display中。
list_display = (‘id‘, ‘title‘, ‘created_time‘, ‘modified_time‘, ‘category‘, ‘author‘, ‘get_read_num‘)
?以上就是文章阅读计数的简单方法,这三种方法的共同缺点就是功能单一,无法统计某一天的阅读数量,下一篇内容将对阅读计数内容进行优化,增加日期的阅读量查询。
原文出处:https://jzfblog.com/detail/55,文章的更新编辑以此链接为准。欢迎关注源站文章!
网站搭建 (第07天) 简单阅读计数
原文地址:https://www.cnblogs.com/djcoder/p/10755646.html