博客閱讀數(shù)的統(tǒng)計(jì)三部曲【一】-3種方式

[TOC]

1.粗略統(tǒng)計(jì)

博客閱讀數(shù)的統(tǒng)計(jì)根據(jù)業(yè)務(wù)的精細(xì)度可以多種方法實(shí)現(xiàn),其中最簡(jiǎn)單的方式就是在models.py定義readed_num字段,然后在打開(kāi)文章詳情頁(yè)時(shí)候給閱讀數(shù)字段+1即可(此方法計(jì)算不準(zhǔn)確,刷新頁(yè)面也會(huì)使得閱讀數(shù)增加,在粗略計(jì)算下可以使用)


blog/models.py
blog/views.py

2.使用cookie統(tǒng)計(jì)

設(shè)置cookie,并獲取cookie來(lái)判斷該篇文章是否閱讀過(guò)
根據(jù)設(shè)置訪問(wèn)文章的cookie的鍵key和值value來(lái)標(biāo)記文章是否被閱讀過(guò),如果閱讀過(guò)設(shè)置cookie,在打開(kāi)文章時(shí)候先獲取cookie來(lái)判斷是否存在,如果不存在,閱讀數(shù)+1;cookie存在則閱讀數(shù)保持不變

存在問(wèn)題
1.每次閱讀數(shù)改變的時(shí)候,admin管理后臺(tái)的更新時(shí)間會(huì)跟著變化
2.當(dāng)管理員在編輯某篇文章,此時(shí)有人點(diǎn)擊該篇文章,閱讀數(shù)增加,但是管理員編輯修改完文章保存后,閱讀數(shù)會(huì)是管理員編輯文章時(shí)候的閱讀數(shù)量

blog/models.py
blog/views.py
def blog_detail(request,blog_pk):
    """博客詳情頁(yè)"""
    blog=get_object_or_404(Blog,pk=blog_pk) # 根據(jù)傳入blog_pk的ID來(lái)找到具體對(duì)應(yīng)博客文章

    # 獲取cookie:根據(jù)獲取cookie的key值'blog_%s_readed' % blog_pk,判斷是否存在,不存在則閱讀數(shù)+1
    if not request.COOKIES.get('blog_%s_readed' % blog_pk):
        blog.readed_num += 1    #點(diǎn)擊該篇文章,閱讀數(shù)自增1
        blog.save()

    pre_blog=Blog.objects.filter(id__gt=blog.id).last() # 博客的上一篇文章
    next_blog=Blog.objects.filter(id__lt=blog.id).first()   # 博客的下一篇文章
    response=render(request,'blog/blog_detail.html',{'blog':blog,'pre_blog':pre_blog,'next_blog':next_blog})    #響應(yīng)
    
    # 設(shè)置cookie,打開(kāi)過(guò)這篇文章即寫(xiě)入cookie,key是'blog_%s_readed' % blog_pk,value是'true'
    response.set_cookie('blog_%s_readed' % blog_pk,'true')
    return response

3.模型分離

Github源碼地址:請(qǐng)點(diǎn)這里

image.png
  • 1.創(chuàng)建模型
    在blog應(yīng)用下面的models.py添加ReadNum類(lèi):


    image.png

代碼示例:

class ReadNum(models.Model):
    read_num=models.IntegerField(default=0,verbose_name='閱讀數(shù)')
    blog=models.OneToOneField(Blog,on_delete=models.DO_NOTHING,verbose_name='標(biāo)題')

    class Meta:
        verbose_name='閱讀數(shù)'
        verbose_name_plural=verbose_name

這種方式可以避免方式2中存在的2個(gè)問(wèn)題

  • 2.同步數(shù)據(jù)庫(kù)操作,模型創(chuàng)建完成后記得:
    python manage.py makemigratiosn
    python manage.py migrate

  • 3.admin.py添加到后臺(tái)管理頁(yè)面


    image.png
class ReadNumAdmin(admin.ModelAdmin):
    list_display=('id','read_num','blog')

admin.site.register(ReadNum,ReadNumAdmin)
  • 為了讓閱讀數(shù)在blog管理頁(yè)面顯示,在models.py的Blog模型添加get_read_num()方法
    注意:此處會(huì)如果謀篇文章暫時(shí)還沒(méi)有閱讀數(shù),默認(rèn)情況下顯示的不是0,而是-,實(shí)際上是拋出了一個(gè)異常,該異常不處理,則顯示閱讀數(shù)是0的顯示-,處理后正常顯示0
    錯(cuò)誤顯示為:
    image.png
image.png
image.png

blog應(yīng)用下面的Blog模型里添加

from django.db.models.fields import exceptions
   
 # 添加方法,添加的read_num方法,用于在admin管理后臺(tái)的blog頁(yè)面顯示閱讀數(shù)。即在admin.py的BlogAdmin類(lèi)的list_display添加read_num
    def get_read_num(self):
        # 返回該篇文章的閱讀數(shù),此處如果該文章還沒(méi)有閱讀數(shù),會(huì)有個(gè)異常,該異常是的默認(rèn)閱讀數(shù)不是0,而是-
        try:
            return self.readnum.read_num
        except exception.ObjectDoesNotExist:
            return 0
  • 4.views.py邏輯處理

此處需要先判斷是否cookie存在,不存在則繼續(xù)判斷該篇文章的閱讀數(shù)是否存在,如果存在則閱讀數(shù)+1并保存數(shù)據(jù)庫(kù);如果不存在,需要先創(chuàng)建該篇文章的閱讀數(shù)(創(chuàng)建是為了在閱讀數(shù)模型保存數(shù)據(jù),具體如下admin管理頁(yè)面截圖),再閱讀數(shù)+1并保存數(shù)據(jù)庫(kù)


image.png
![image.png](http://upload-images.jianshu.io/upload_images/545178-9a550efc95446394.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
def blog_detail(request,blog_pk):
    """博客詳情頁(yè)"""
    blog=get_object_or_404(Blog,pk=blog_pk) # 根據(jù)傳入blog_pk的ID來(lái)找到具體對(duì)應(yīng)博客文章

    # 獲取cookie:根據(jù)獲取cookie的key值'blog_%s_readed' % blog_pk,判斷是否存在,不存在則閱讀數(shù)+1
    if not request.COOKIES.get('blog_%s_read' % blog_pk):
        if ReadNum.objects.filter(blog=blog).count():
            # 記錄存在,則查詢并閱讀數(shù)+1,保存
            readnum=ReadNum.objects.get(blog=blog)
        else:
            # 對(duì)應(yīng)記錄不存在,則創(chuàng)建并閱讀數(shù)+1,保存(這樣就會(huì)在閱讀數(shù)管理頁(yè)面點(diǎn)擊后保存對(duì)應(yīng)文章以及閱讀數(shù))
            readnum=ReadNum(blog=blog)
        readnum.read_num += 1    #點(diǎn)擊該篇文章,閱讀數(shù)自增1
        readnum.save()

    pre_blog=Blog.objects.filter(id__gt=blog.id).last() # 博客的上一篇文章
    next_blog=Blog.objects.filter(id__lt=blog.id).first()   # 博客的下一篇文章
    response=render(request,'blog/blog_detail.html',{'blog':blog,'pre_blog':pre_blog,'next_blog':next_blog})    #響應(yīng)
    
    # 設(shè)置cookie,打開(kāi)過(guò)這篇文章即寫(xiě)入cookie,key是'blog_%s_readed' % blog_pk,value是'true'
    response.set_cookie('blog_%s_read' % blog_pk,'true')
    return response
  • 5.修改html模版文件閱讀的顯示
    直接使用Blog模型中的get_read_num()方法


    image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容