【Django2.0学习笔记】20.阅读计数统计和显示

20、阅读计数统计和显示

1、简单计数方法的缺点

  • 1、后台编辑博客可能影响数据
  • 2、功能单一,无法统计某一天的阅读数
    在这里插入图片描述
    本节想要实现的效果如下:
    在这里插入图片描述

2、统计需要记录明细

例如:
阅读量120 —> 2月1号 阅读量20、 2月2号 阅读量60、2月3号 阅读量40
在这里插入图片描述

1、模型models
修改read_statistics\models.py代码如下:
在这里插入图片描述

数据库同步:
在这里插入图片描述

2、admin
修改admin.p如下:
在这里插入图片描述

启动服务器,刷新页面
在这里插入图片描述
添加一条记录
在这里插入图片描述
在这里插入图片描述

接下来我们要考虑一个问题,这个数据我们怎么加 什么时候加 怎么去统计单天或者对应博客阅读数量,这里可能有一种思路,就是记录每条每次打开博客详情,每次都有一个日期时间,最后把它统计汇总填到我们刚刚的模型。这个方法可行,但麻烦。
另外还有一种,在utils.py里既然有一个阅读数量添加的判断处理,那么也可以在这个地方,我们当天打开第一篇博客,那么我们就可以加上一条明细

修改utils.py如下:
在这里插入图片描述

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\read_statistics\utils.py
from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from .models import ReadNum, ReadDetail

def read_statistics_once_read(request, obj):
	ct = ContentType.objects.get_for_model(obj)
	key = "%s_%s_read" % (ct.model, obj.pk)	# 模型名称,主键值
	# 对应views.py中判断cookie是否存在:if not request.COOKIES.get('blog_%s_read' % blog_pk),和设置cookie的方法: response.set_cookie('blog_%s_read' % blog_pk, 'true')

	if not request.COOKIES.get(key): # 当不存在这个键值的时候,我们才进行阅读加1的操作
		# ct = ContentType.objects.get_for_model(Blog)
		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)
		# 计数加1
		readnum.read_num +=1
		readnum.save()

		date = timezone.now().date()
		if ReadDetail.objects.filter(content_type=ct, object_id=obj.pk, date=date).count():
			readDetail = ReadDetail.objects.get(content_type=ct, object_id=obj.pk, date=date)
		else:
			readDetail = ReadDetail(content_type=ct, object_id=obj.pk, date=date)
		readDetail.read_num += 1
		readDetail.save()

	return key

在这里插入图片描述
在这里插入图片描述

下面讲更简单的方法:
上面的逻辑判断实际上是一个处理逻辑,我们获取我们想要的记录,如果不存在就创建。这种django提供了一个叫做get_or_create的方法(获取某内容,如果获取不到,就创建),我们通过shell 或者查看django官方文档都能找到
在这里插入图片描述
在这里插入图片描述
可以修改utils.py如下:
在这里插入图片描述

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\read_statistics\utils.py
from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from .models import ReadNum, ReadDetail

def read_statistics_once_read(request, obj):
	ct = ContentType.objects.get_for_model(obj)
	key = "%s_%s_read" % (ct.model, obj.pk)	# 模型名称,主键值
	# 对应views.py中判断cookie是否存在:if not request.COOKIES.get('blog_%s_read' % blog_pk),和设置cookie的方法: response.set_cookie('blog_%s_read' % blog_pk, 'true')

	if not request.COOKIES.get(key):
		# 总阅读数 +1
		# 返回结果:第一个是我们所需要对象,第二个表示是否创建(如果是创建的,为true;如果是获取到的,为false
		readnum, created = ReadNum.objects.get_or_create(content_type=ct, object_id=obj.pk) 
		readnum.read_num +=1
		readnum.save()

		# 当天阅读数 +1
		date = timezone.now().date()
		readDetail, created = ReadDetail.objects.get_or_create(content_type=ct, object_id=obj.pk, date=date)
		readDetail.read_num += 1
		readDetail.save()
	return key

接下来,我们要展示什么数据、如何把数据展示出来

第一步,要展示什么数据
这里,我们先获取前面七天的阅读数据
修改utils.py如下:【range(-6, -1, -1) 】
在这里插入图片描述

import datetime
from django.db.models import Sum

def get_seven_days_read_data(content_type):	# 我们要做成一个通用的统计方法,所以这里传入content_type类型这个参数
	today = timezone.now().date() # 获取当天日期
	read_nums = []
	# for i in range(7, 0, -1):
	for i in range(6, -1, -1):
		date = today - datetime.timedelta(days=i)	# timedelta:差值
		read_details = ReadDetail.objects.filter(content_type=content_type, date=date)
		result = read_details.aggregate(read_num_sum=Sum('read_num')) # 对read_num字段进行求和,取名为read_num_sum
		read_nums.append(result['read_num_sum'])
	return read_nums

其中的aggregate方法在shell中展示如下:
在这里插入图片描述

然后我们想要在前端页面的首页中显示这个数据,那么可以修改mysite/views.py如下:
在这里插入图片描述

from django.shortcuts import render_to_response
from django.contrib.contenttypes.models import ContentType
from read_statistics.utils import get_seven_days_read_data
from blog.models import Blog


def home(request):
	blog_content_type = ContentType.objects.get_for_model(Blog)
	dates, read_nums = get_seven_days_read_data(blog_content_type)

	context = {}
	context['dates'] = dates
	context['read_nums'] = read_nums
	return render_to_response('home.html', context)

接下来我们改一下对应的模板页面,修改home.html如下:
在这里插入图片描述

刷新页面的首页,效果如下
在这里插入图片描述
想要将None显示为0
修改utils.py如下:
在这里插入图片描述

在这里插入图片描述
接下来,我们想要用更好看的方式显示出来,这里我们想要用图表比较好

3、使用图表显示数据

  • 后台 + 前端
  • 后台提供数据,前端使用数据
    在这里插入图片描述
    我们使用的是 Highcharts ,将以下示例代码直接复制到home.html
    在这里插入图片描述

然后对应的修改home.html如下:
在这里插入图片描述
在这里插入图片描述

<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\templates\home.html -->
<!-- 首页的模板页面 -->
{% extends 'base.html' %}
{% load staticfiles %}

{% block title %}
	我的网站 | 首页
{% endblock %}

{% block nav_home_active %}active{% endblock %}

{% block header_extends %}
	<link rel="stylesheet" type="text/css" href="{% static 'home.css' %}">
	<!-- 引入 highcharts.js -->
	<script src="http://cdn.highcharts.com.cn/highcharts/highcharts.js"></script>
{% endblock %}

{% block content %}
	<h3 class="home-content">欢迎访问我的网站,随便看</h3>
<!-- 	<p>{{ read_nums }}</p> -->

	<!-- 图表容器 DOM -->
    <div id="container" style="width: 600px;height:400px;"></div>
    <script>
        // 图表配置
        var options = {
            chart: {
                type: 'line'                          //指定图表的类型,默认是折线图(line)
            },
            title: {
                text: null              // 标题、不需要则设置为null
            },
            xAxis: {
                categories: {{ dates|safe }},  // x 轴分类
                tickmarkPlacement: 'on',
                title: { text: '前7日阅读量变化' },
            },
            yAxis: {
                title: { text: null },          // y 轴标题
               	labels:{ enabled: false },	//去掉左侧的坐标轴显示内容
               	gridLineDashStyle: 'Dash', //坐标横格线设置为虚线
            },
            series: [{                              // 数据列
                name: '阅读量',                        // 数据列名
                data: {{ read_nums }}                    // 数据

            }],
            plotOptions: {		//数据标签(dataLables)。从官方文档中复制代码过来
			    line: {
			        dataLabels: {
			            enabled: true
			        }
			    }
			},

            legend: { enabled: false }, //图例。通过设置 legend.enabled = true | false 来打开或关闭图例。https://www.highcharts.com.cn/docs/basic-legend
            credits: { enabled: false }, //图表版权信息。显示在图表右下方的包含链接的文字,默认的文字是 Highcharts,链接是Highcharts官网地址。通过指定credits.enabled=false即可不显示该信息。
        };
        // 图表初始化函数
        var chart = Highcharts.chart('container', options);
    </script>
{% endblock %}

我们需要拿到日期数组,所以也需要返回date,修改utils.py如下:
在这里插入图片描述
修改views.py如下:
在这里插入图片描述
接下来,我们调整页面布局,修改home.css如下:
在这里插入图片描述

h3.home-content {
	font-size: 222%;	/*字体*/
	text-align: center; /*文本居中*/
	margin-top: 4em; /*文本上边距*/
	margin-bottom: 2em; /*文本下边距*/
}

/*图表设置居中*/
div#container {	
	margin: 0 auto;
	height: 20em;
	min-width: 20em;
	max-width: 30em;

刷新页面
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值