阅读计数功能实现

阅读计数功能实现

 

 

最简单的方法:用户访问一次,则认为是一次请求,对本表的字段进行计数,使用cookie进行状态保存。

 

1
2
1.添加字段
read_count=models.IntegerField(default=0)

 

复制代码
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
models
复制代码

 

1
2
3
2.数据库
python manage.py makemigrations
python manage.py migrate 

  

1
2
3.admin里list_display
list_display = ('read_count',)

  

 

1
2
3
4
5
6
7
8
4.view<br>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
复制代码
#具体博文
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
view
复制代码
1
2
3
4
5
服务器要做的工作:判断客户端访问状态,没有cookie进行操作,有cookie不操作,某台客户端访问过某篇文章,设置一个cooike,并设置过期时间
max-age单位为秒
expries指定一个过期时间,为datatime
如果不设置过期时间,关闭浏览器cookie自动实现
ret.set_cookie('blog_%s_readed'%nid,'true',max-age=3600)

  

 

1
5.在模板里配置,显示数据

  

1
2
3
4
虽然这种方法适用性很强,但是还是有缺点的。<br>缺点:
如果此时正在编辑后台数据,用户在访问博客文章,此时的阅读计数功能并不会生效,影响数据有效性。
功能单一,计数功能没有独立出来。
无法统计某一天的阅读数。

  

 

第二种方法:重新创建一个模型,单独来做计数功能,一对一的关系

1
2
3
4
5
6
7
8
9
10
1.创建模型和方法<br>#为关联表的方法,获取计数并返回
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)

  

复制代码
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)
models
复制代码

 

 

1
2
2.在admin中设置,通过方法名
display('get_read_num',)

  

1
2
3
4
5
6
7
8
9
10
11
12
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()

 

复制代码
#具体博文
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
View
复制代码

 

 

1
2
3
4.数据库
python manage.py makemigrations
python manage.py migrate 

  

 

1
2
5.在模板中获取记录信息,直接调用方法
blog.get_read_num

  

 

占位,后面补上!!!

 

posted @   -零  阅读(448)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示