我的网站搭建: (第八天) 阅读计数优化

简介:     上篇写了几个简单的阅读计数,其缺点都是无法统计某一天的阅读数量,也就无法根据日期来对热门博客进行排行。所以最好还是重建一个带有日期字段名的模型表,这就可以根据日期条件来筛选博客的阅读次数了,比较方便统计。

    上篇写了几个简单的阅读计数,其缺点都是无法统计某一天的阅读数量,也就无法根据日期来对热门博客进行排行。所以最好还是重建一个带有日期字段名的模型表,这就可以根据日期条件来筛选博客的阅读次数了,比较方便统计。ReadNum继续保留,再建一个ReadDetail模型类

from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType

class ReadDetail(models.Model):
    """
        根据日期计数的模型类
        继承model.Model模型类
    """
    read_num = models.IntegerField(default=0)
    date = models.DateField(default=timezone.now)

    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    class Meta:
        verbose_name = '阅读记录'
        verbose_name_plural = '阅读记录'
        ordering = ['-date']

    做到这一步,就应该对read_num的数值进行计数了。这个计数还不能每次点击进入read_num都会增加,否则这个数值就没有意义了,应当是只要是同一个用户在段时间重复进入多次,数值只会变化+1,而不是每次进入都会增加。因为这个状态是不涉及重要信息的,所以直接用cookie来进行状态保持的记录就可以了,通过request.COOKIES.get(key)来获取key的值,如果获取不到,则说明用户还未点击这篇博客,可以对read_num进行+1逻辑处理。同时当没有ReadNumReadDetail的实例对象时,就要创建,这里可以使用get_or_create方法,返回两个参数

from django.contrib.contenttypes.models import ContentType

def read_statistics_once_read(request, obj):
    """
        作用:阅读+1的处理逻辑功能
        request:请求对象
        obj:post实例对象
    """
    ct = ContentType.objects.get_for_model(obj)
    key = "%s_%s_read" % (ct.model, obj.pk)
    if not request.COOKIES.get(key):
        # 如果使用get_or_create就能省略上面一大段,可以简化
        readnum, created = ReadNum.objects.get_or_create(content_type=ct, object_id=obj.pk)

        # 总阅读计数+1
        readnum.read_num += 1
        readnum.save()

        # 当天阅读数+1
        date = timezone.now().date()
        readdetail, created = ReadDetail.objects.get_or_create(content_type=ct, object_id=obj.pk, date=date)
        readdetail.read_num += 1
        readdetail.save()
    return key

    上面是对每篇博客阅读+1的处理,可以看到该函数返回了一个key,通过对key赋值可以实现状态保持。下面代码还有上一篇下一篇博客的逻辑部分,这里也顺便贴出来了

def detail(request, pk):
    """
        作用:显示当前选择文章内容
        request:请求对象
        pk:每篇文章的pk值
    """
    # 接收了一个pk值,这个值是在url中传递的主键,利用该主键可以找到文章的对象
    # get_object_or_404的用法是(模型名,get方法)
    post = get_object_or_404(Post, pk=pk)
    post_all_list = Post.objects.all()

    # read_statistics_once_read是在read_statistics应用中的方法,表示计数+1
    read_cookie_key = read_statistics_once_read(request, post)

    # 在django中不能使用>=或<=,所以django自定义了__gt和__lt
    # 目的:得出创建时间比当前博客创建时间较晚的所有博客列表的最后一篇博客,也就是当前博客的上一篇
    # 因为博客是按照创建时间的先后来排序的:即先创建的靠后,那么上一篇博客创建时间晚于当前博客
    previous_post = Post.objects.filter(created_time__gt=post.created_time).last()

    # 目的:得出创建时间比当前博客创建时间较早的所有博客列表的第一篇博客,也就是当前博客的下一篇
    # 因为博客是按照创建时间的先后来排序的:即先创建的靠后,那么上一篇博客创建时间早于当前博客
    next_post = Post.objects.filter(created_time__lt=post.created_time).first()

    context = ({'article': post.body, 'title': post.title,
                'author': post.author, 'created_time': post.created_time,
                'category': post.category, 'previous_post': previous_post,
                'next_post': next_post, 'read_num': post.get_read_num,
                'user': request.user, 'post_id': post.id, 'post': post,
               })
    response = render(request, 'blog/detail.html', context)
    # 第一个参数是键,键值,和过期时间
    response.set_cookie(read_cookie_key, 'true')  # 阅读cookie标记
    return response

    到这里就基本就是阅读计数优化的全部内容。

相关文章
|
5月前
|
人工智能 算法
【阅读】一周翻过《构建之法》,笔记整理
🚩 前言 我的阅读方式 我拿到这本书挺久了,之前已经零散地看过一部分,最近一周集中地花了一些时间,将整本书看过了一遍。看得比较粗略,正如“好读书,不求甚解”(我甚至没有去看书中提到的那些参考资料)。
44 0
我写了一个自动化脚本涨粉,从0阅读到接近100粉丝(二)
我写了一个自动化脚本涨粉,从0阅读到接近100粉丝
97 0
【期末不挂科-单片机考前速过系列P6】(第六章:10题速过定时计数器的结构和工作方式例题)经典例题盘点(带图解析)
【期末不挂科-单片机考前速过系列P6】(第六章:10题速过定时计数器的结构和工作方式例题)经典例题盘点(带图解析)
|
3月前
|
数据采集 前端开发 NoSQL
《花100块做个摸鱼小网站!· 序》灵感来源
# 序 大家好,我是summo。去年趁阿里云99元一年的2核2G服务器优惠,我买了一台,起初用于练手Linux和部署数据库等环境,后来决定搭建一个摸鱼小网站。受摸鱼网站启发,创建了[上班摸鱼](https://sbmy.fun),一个聚合热搜的网页。总花费109元(含10元域名),用两周摸鱼时间完成。虽未广泛推广,已有2万访问量。计划分享搭建过程,包括技术调研、爬虫编写等。一起动手,100元获得实操经验!]
82 1
《花100块做个摸鱼小网站!· 序》灵感来源
|
5月前
|
小程序 JavaScript Java
基于Java的大学生心理健康答题小程序设计与实现(亮点:选题新颖、可以发布试卷设置题目、自动判卷、上传答案、答案解析)
基于Java的大学生心理健康答题小程序设计与实现(亮点:选题新颖、可以发布试卷设置题目、自动判卷、上传答案、答案解析)
86 0
|
10月前
|
测试技术
【测试平台系列】第一章 手撸压力机(十)-定义场景
上一章,咱们对http请求进行了一些优化,本章节我们将组成场景去运行。首先场景就是一连串的http接口的请求,我们使用list(列表)来组装成一个场景
【测试平台系列】第一章 手撸压力机(十)-定义场景
|
10月前
|
存储 JSON 搜索推荐
【测试平台系列】第一章 手撸压力机(十二)-初步实现提取功能
上一章节,我们主要实现了基础的并发测试场景的能力。本章节,我们实现一下,如何对响应进行提取,使用正则/json对响应信息提取,并赋值给我们定义的变量。
|
数据采集 Web App开发 JavaScript
我写了一个自动化脚本涨粉,从0阅读到接近100粉丝(一)
我写了一个自动化脚本涨粉,从0阅读到接近100粉丝
110 0
蓝桥杯之单片机学习(二十一)——自动售水机(附题目和完整代码)
蓝桥杯之单片机学习(二十一)——自动售水机(附题目和完整代码)
358 0
蓝桥杯之单片机学习(二十一)——自动售水机(附题目和完整代码)
|
Web App开发 存储 前端开发
【番外01】吐血整理5万字100道高频基础面试题 无名面试集《烂俗前端》
【番外01】吐血整理5万字100道高频基础面试题 无名面试集《烂俗前端》
189 0