[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ì)算下可以使用)


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ù)量


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)這里

-
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


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ù)


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



