zoukankan      html  css  js  c++  java
  • 【7】网站搭建:简单阅读计数

    一、前言

      如果知道每篇文章的浏览量,管理员就可以了解到访问者对文章的喜好程度,方便后续推出相关内容文章,同时对热门博客的统计和阅读趋势图打好基础。针对阅读统计功能,前前后后我一共想到了三种方法,各种方法都有利有弊。

    二、采用该模型字段计数

        ​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,文章的更新编辑以此链接为准。欢迎关注源站文章!

    作者:蒋振飞
    此内容均来自个人原创以及互联网转载和摘录,仅供学习交流使用,并非商业用途,欢迎转载。
  • 相关阅读:
    Android Animations动画使用详解
    android LinearLayout和RelativeLayout实现精确布局
    中国天气网API
    获取中央气象台API 完整城市列表简单方式
    Django框架 连接Oracle -ServerName方式报错
    关于java的动态代理
    Mybatis缓存
    Git使用,将本地项目推送到GitHub上
    使用doxc4j将word转pdf遇到的一个问题
    linux安装jdk
  • 原文地址:https://www.cnblogs.com/djcoder/p/10755646.html
Copyright © 2011-2022 走看看