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

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

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

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

相关文章
|
9月前
|
算法 C++ 容器
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(上)
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(上)
31 0
|
9月前
|
存储 算法 决策智能
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(下)
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(下)
55 0
|
6月前
|
测试技术 Go
【测试平台系列】第一章 手撸压力机(七)- 使用gin
今天,我们使用gin框架将压力机做成一个web服务后端。 我们引入gin框架:
【测试平台系列】第一章 手撸压力机(七)- 使用gin
|
6月前
|
存储 JSON 搜索推荐
【测试平台系列】第一章 手撸压力机(十二)-初步实现提取功能
上一章节,我们主要实现了基础的并发测试场景的能力。本章节,我们实现一下,如何对响应进行提取,使用正则/json对响应信息提取,并赋值给我们定义的变量。
|
10月前
|
前端开发 定位技术
前端学习笔记202305学习笔记第二十三天-网上地图资源获取1
前端学习笔记202305学习笔记第二十三天-网上地图资源获取1
31 0
|
前端开发
前端学习笔记202304学习笔记第七天-学习目标
前端学习笔记202304学习笔记第七天-学习目标
47 0
|
缓存 算法
消除游戏系列教程大合集
今天给大家带来一份消除游戏系列教程大合集,谦虚的讲这应该是全网你能找到的最好的消除游戏系列教程(反正我是没找到更好的)。这年头儿,像小蚂蚁这样的,虽然没几个人看但还在孜孜不倦的写教程的人已经不多了,所以大家且看且珍惜,一定要记得收藏,虽然收藏了你也不会看,但是至少有个心理安慰。如果对你有用的话,不要忘了点赞分享一下,也算是对我的鼓励了。
53 0
|
传感器
时隔这么长时间,我把常用的功能整理好了,再来感受VueUse工具库的优雅吧~
时隔这么长时间,我把常用的功能整理好了,再来感受VueUse工具库的优雅吧~
时隔这么长时间,我把常用的功能整理好了,再来感受VueUse工具库的优雅吧~
|
前端开发
带你读书之“红宝书”:第三章 语法基础(上)之 关键词后续
带你读书之“红宝书”:第三章 语法基础(上)之 关键词后续
81 0
带你读书之“红宝书”:第三章 语法基础(上)之 关键词后续
|
资源调度 Java
【蓝桥杯Java_C组·从零开始卷】第四节(附)、河图洛书【九宫格】(卷王必备,不想卷的略过,使用优化暴力破解,与网上莫名其妙的规律不一样)
【蓝桥杯Java_C组·从零开始卷】第四节(附)、河图洛书【九宫格】(卷王必备,不想卷的略过,使用优化暴力破解,与网上莫名其妙的规律不一样)
212 1
【蓝桥杯Java_C组·从零开始卷】第四节(附)、河图洛书【九宫格】(卷王必备,不想卷的略过,使用优化暴力破解,与网上莫名其妙的规律不一样)