以前寫了單篇博客的閱讀量統計,今天添加了博客總閱讀量統計,而且使用highcharts圖表顯示。css
一、變化的部分html
二、上代碼:django
# -*- coding: utf-8 -*- # @Time : 18-11-7 下午4:12 # @Author : Felix Wang 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(requests): blog_content_type = ContentType.objects.get_for_model(Blog) dates, read_nums = get_seven_days_read_data(blog_content_type) context = { 'read_nums': read_nums, 'dates': dates, } return render_to_response('home.html', context)
from django.contrib import admin from .models import ReadNum, ReadDetail # Register your models here. @admin.register(ReadNum) class ReadNumAdmin(admin.ModelAdmin): list_display = ('read_num', 'content_object') @admin.register(ReadDetail) class ReadNumAdmin(admin.ModelAdmin): list_display = ('date', 'read_num', 'content_object')
from django.db import models from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db.models.fields import exceptions from django.utils import timezone # Create your models here. # 使用到了contenttype 參考網址:https://docs.djangoproject.com/en/2.1/ref/contrib/contenttypes/ class ReadNum(models.Model): read_num = models.IntegerField(default=0) # 閱讀量 content_type = models.ForeignKey(ContentType, on_delete=models.DO_NOTHING) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') def __str__(self): return str(self.read_num) # 閱讀計數擴展方法 class ReadNumExpandMethod: def get_read_num(self): # 獲取一對一關聯的閱讀數 try: ct = ContentType.objects.get_for_model(self) readnum = ReadNum.objects.get(content_type=ct, object_id=self.pk) return readnum.read_num except exceptions.ObjectDoesNotExist as e: return 0 class ReadDetail(models.Model): date = models.DateField(default=timezone.now) read_num = models.IntegerField(default=0) # 閱讀量 content_type = models.ForeignKey(ContentType, on_delete=models.DO_NOTHING) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id')
# -*- coding: utf-8 -*- # @Time : 18-11-17 下午10:03 # @Author : Felix Wang import datetime from django.contrib.contenttypes.models import ContentType from django.db.models import Sum from django.utils import timezone from .models import ReadNum, ReadDetail def read_statistics_once_read(requests, obj): ct = ContentType.objects.get_for_model(obj) key = '{}_{}_read'.format(ct.model, obj.pk) # 獲取並處理閱讀計數 if not requests.COOKIES.get(key): # 總閱讀量+1 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 def get_seven_days_read_data(content_type): today = timezone.now().date() dates = [] read_nums = [] for i in range(7, 0, -1): date = today - datetime.timedelta(days=i) dates.append(date.strftime('%m/%d')) read_details = ReadDetail.objects.filter(content_type=content_type, date=date) result = read_details.aggregate(read_num_sum=Sum('read_num')) read_nums.append(result['read_num_sum'] or 0) return dates, read_nums
.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; }
{% extends 'base.html' %} {% load staticfiles %} {% block header_extends %} <link rel="stylesheet" href="{% static 'css/home.css' %}"> <script src="{% static 'Highcharts-6.2.0/code/highcharts.js' %}"></script> {% endblock %} {% block title %} 個人博客|首頁 {% endblock %} {% block content %} <h1 class="home-content">歡迎訪問個人博客</h1> <!-- 圖表容器 DOM --> <div id="container"></div> <!-- 引入 highcharts.js --> <script> // 圖表配置 let options = { chart: { type: 'line' //指定圖表的類型,默認是折線圖(line) }, title: { text: null // 標題 }, xAxis: { categories: {{ dates|safe }} // x 軸分類 }, yAxis: { title: { text: null // y 軸標題 }, labels: { enabled: false }, gridLineDashStyle: 'Dash', }, plotOptions: { line: { dataLabels: { enabled: true } } }, credits: { enabled: false // 禁用版權信息 }, series: [{ // 數據列 name: '閱讀量', // 數據列名 data: {{ read_nums }},// 數據 showInLegend: false, // 設置爲 false 即爲不顯示在圖例中 },] }; // 圖表初始化函數 let chart = Highcharts.chart('container', options); </script> {% endblock %} {% block js %} {# 將首頁這個按鈕設置激活狀態 #} <script> $(".nav-home").addClass("active").siblings().removeClass("active"); </script> {% endblock %}
三、解釋app
這裏使用了圖表框架highcharts,官網:官方文檔框架