個人網站搭建 (第七天) 簡單閱讀計數

    若是知道每篇文章的瀏覽量,管理員就能夠了解到訪問者對文章的喜愛程度,方便後續推出相關內容文章,同時對熱門博客的統計和閱讀趨勢圖打好基礎。針對閱讀統計功能,前先後後我一共想到了三種方法,各類方法都有利有弊。python

採用該模型字段計數django

1.修改Post模型read_numcookie

2.優化:設置cookie判斷是否用戶屢次點擊response.set_cookie()
    優勢:簡單
    缺點:1.後臺編輯博客可能影響數據
               2.功能單一,沒法統計某一天的閱讀數量工具

3.具體實現:post

    ​在Post模型類中直接定義一個read_num的字段名優化

read_num = models.IntegerField(default=0)

​    ​而後能夠經過對Post屬性read_num的操做來實現閱讀計數+1的邏輯處理設計

post.read_num += 1
    post.save()

設計功能獨立的ReadNum模型數據表code

1.添加read_num字段對象

2.增長post外鍵blog

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

1.導入兩個模塊GenericForeignKey和ContentType(很是重要)

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

2.新增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']

3.新增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()

4.解決後臺計數對象沒建立時的解決辦法,新增一個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):  
    ...

5.將方法加入到blog/amdin.py中的list_display中

list_display = ('id', 'title', 'created_time', 'modified_time', 'category', 'author', 'get_read_num')

    以上就是文章閱讀計數的簡單方法,這三種方法的共同缺點就是功能單一,沒法統計某一天的閱讀數量,下一篇內容將對閱讀計數內容進行優化,增長日期的閱讀量查詢

相關文章
相關標籤/搜索