阅读计数功能实现
最简单的方法:用户访问一次,则认为是一次请求,对本表的字段进行计数,使用cookie进行状态保存。
1.添加字段
read_count=models.IntegerField(default=0)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
from django.db import models from django.contrib.auth.models import User from ckeditor_uploader.fields import RichTextUploadingField # Create your models here. class BlogType(models.Model): type_name=models.CharField(max_length=15,verbose_name="博客类型") def __str__(self): return self.type_name class Blog(models.Model): #博客标题 title=models.CharField(max_length=50,verbose_name="文章标题") #博客类型 blog_type=models.ForeignKey(BlogType,on_delete=models.DO_NOTHING,verbose_name="博客类型") #博客作者 author=models.ForeignKey(User,on_delete=models.DO_NOTHING,verbose_name="作者") #博客内容 content=RichTextUploadingField() #创建文章的时间 created_time=models.DateTimeField(auto_now_add=True,verbose_name="发表时间") #最后修改的时间 last_updated_time=models.DateTimeField(auto_now=True,verbose_name="最后修改时间") #日期 date = models.DateField(auto_now_add=True,verbose_name="日期") read_count = models.IntegerField(default=0) def __str__(self): return self.title
2.数据库
python manage.py makemigrations
python manage.py migrate
3.admin里list_display
list_display = ('read_count',)
4.view
ret = render(request, "blog_detail.html", {"blog": blog, "previos_blog": previos_blog, 'next_blog': next_blog})
#如果没有获取到COOKIES,则说明用户第一次访问,进行计数,并设置cookie,客户端第二次访问以后,则会获取到cookie,不进行计数操作
# 当cookies过期,服务端会再一次获取不到cookies,认为是新的用户,则会进行计数,并重新设置cookie
if not request.COOKIES.get('blog_%s_readed' % nid):
blog.read_count += 1
blog.save()
ret.set_cookie('blog_%s_readed' % nid, 'true', max_age = 3600)
return ret
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#具体博文 def get_blog_detial(request): nid=request.GET.get('nid') print(nid) # blog = Blog.objects.all() blog=Blog.objects.filter(id=nid) print(blog[0].created_time) #日期比这篇博客大,则为后更新的博客 next_blog=Blog.objects.filter(created_time__gt=blog[0].created_time).first() # 日期比这篇博客小,则为前面更新的博客 previos_blog=Blog.objects.filter(created_time__lt=blog[0].created_time).last() ret = render(request, "blog_detail.html", {"blog": blog, "previos_blog": previos_blog, 'next_blog': next_blog}) #如果没有获取到COOKIES,则说明用户第一次访问,进行计数,并设置cookie,客户端第二次访问以后,则会获取到cookie,不进行计数操作 # 当cookies过期,服务端会再一次获取不到cookies,认为是新的用户,则会进行计数,并重新设置cookie if not request.COOKIES.get('blog_%s_readed' % nid): blog.read_count += 1 blog.save() ret.set_cookie('blog_%s_readed' % nid, 'true', max_age = 60) return ret
服务器要做的工作:判断客户端访问状态,没有cookie进行操作,有cookie不操作,某台客户端访问过某篇文章,设置一个cooike,并设置过期时间
max-age单位为秒
expries指定一个过期时间,为datatime
如果不设置过期时间,关闭浏览器cookie自动实现
ret.set_cookie('blog_%s_readed'%nid,'true',max-age=3600)
5.在模板里配置,显示数据
虽然这种方法适用性很强,但是还是有缺点的。
缺点:
如果此时正在编辑后台数据,用户在访问博客文章,此时的阅读计数功能并不会生效,影响数据有效性。
功能单一,计数功能没有独立出来。
无法统计某一天的阅读数。
第二种方法:重新创建一个模型,单独来做计数功能,一对一的关系
1.创建模型和方法
#为关联表的方法,获取计数并返回
def get_read_num(self):
return self.readnum.read_num
#计数模型
class ReadNum(model.Model):
#计数字段
read_num=models.IntergerField(default=0)
#关联字段
blog=models.OneToOneField(Blog,on_delete=models.DO_NOTHING)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
from django.db import models from django.contrib.auth.models import User from ckeditor_uploader.fields import RichTextUploadingField # Create your models here. class BlogType(models.Model): type_name=models.CharField(max_length=15,verbose_name="博客类型") def __str__(self): return self.type_name class Blog(models.Model): #博客标题 title=models.CharField(max_length=50,verbose_name="文章标题") #博客类型 blog_type=models.ForeignKey(BlogType,on_delete=models.DO_NOTHING,verbose_name="博客类型") #博客作者 author=models.ForeignKey(User,on_delete=models.DO_NOTHING,verbose_name="作者") #博客内容 content=RichTextUploadingField() #创建文章的时间 created_time=models.DateTimeField(auto_now_add=True,verbose_name="发表时间") #最后修改的时间 last_updated_time=models.DateTimeField(auto_now=True,verbose_name="最后修改时间") #日期 date = models.DateField(auto_now_add=True,verbose_name="日期") def __str__(self): return self.title # 为关联表的方法,获取计数并返回 def get_read_num(self): return self.readnum.read_num #计数模型 class ReadNum(models.Model): #计数字段 read_num=models.IntegerField(default=0) #关联字段 blog=models.OneToOneField(Blog,ondelete=models.DO_NOTHING)
2.在admin中设置,通过方法名
display('get_read_num',)
3.view
#首先判断是否有这条博客的记录信息
if ReadNum.objects.filter(blog=blog).count():
#如果存在记录信息,获取记录的信息
readnum=ReadNum.objects.get(blog=blog)
else:
#如果没有,则创建这条博客的记录
readnum=ReadNum(blog=blog)
#存在与不存在记录都要进行计数+1
readnum.read_num+=1
readnum.save()
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#具体博文 def get_blog_detial(request): nid=request.GET.get('nid') print(nid) # blog = Blog.objects.all() blog=Blog.objects.filter(id=nid) print(blog[0].created_time) #日期比这篇博客大,则为后更新的博客 next_blog=Blog.objects.filter(created_time__gt=blog[0].created_time).first() # 日期比这篇博客小,则为前面更新的博客 previos_blog=Blog.objects.filter(created_time__lt=blog[0].created_time).last() ret = render(request, "blog_detail.html", {"blog": blog, "previos_blog": previos_blog, 'next_blog': next_blog}) #如果没有获取到COOKIES,则说明用户第一次访问,进行计数,并设置cookie,客户端第二次访问以后,则会获取到cookie,不进行计数操作 # 当cookies过期,服务端会再一次获取不到cookies,认为是新的用户,则会进行计数,并重新设置cookie if not request.COOKIES.get('blog_%s_readed' % nid): # 首先判断是否有这条博客的记录信息 if ReadNum.objects.filter(blog=blog).count(): # 如果存在记录信息,获取记录的信息 readnum = ReadNum.objects.get(blog=blog) else: # 如果没有,则创建这条博客的记录 readnum = ReadNum(blog=blog) # 存在与不存在记录都要进行计数+1 readnum.read_num += 1 readnum.save() ret.set_cookie('blog_%s_readed' % nid, 'true', max_age = 3060) return ret
4.数据库
python manage.py makemigrations
python manage.py migrate
5.在模板中获取记录信息,直接调用方法
blog.get_read_num
占位,后面补上!!!