网站搭建 (第07天) 简单阅读计数
Posted djcoder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网站搭建 (第07天) 简单阅读计数相关的知识,希望对你有一定的参考价值。
一、前言
如果知道每篇文章的浏览量,管理员就可以了解到访问者对文章的喜好程度,方便后续推出相关内容文章,同时对热门博客的统计和阅读趋势图打好基础。针对阅读统计功能,前前后后我一共想到了三种方法,各种方法都有利有弊。
二、采用该模型字段计数
?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 += 1 readnum.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 GenericForeignKey from django.contrib.contenttypes.models import ContentType
新增ReadNum模型表,创建read_num这个字段名。
from django.db import models from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType class 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天) 简单阅读计数的主要内容,如果未能解决你的问题,请参考以下文章