21.热门博客排行以及缓存提速
Github链接地址:Github地址
[toc]
一、利用阅读数量排行
1.24小时内
read_statistics/utils.py
- 首先在read_statistics/utils.py文件里新建今天阅读数量QuerySet的方法:get_today_hot_data(),按照阅读量从多到少排序,取出数量最多的前7条数据
read_statistics/utils.py
def get_today_hot_data(content_type):
'''获取今天24小时阅读数量-按照阅读量从多到少排序'''
today = timezone.now().date() #当天的时间
read_details = ReadDetail.objects.filter(content_type=content_type,date=today).order_by('-read_num')[:7]
return read_details
- 然后在yhsite/views.py里面引用get_today_hot_data方法并且返回数据给前台home.html页面
yhsite/views.py
from django.shortcuts import render
from django.contrib.contenttypes.models import ContentType
from read_statistics.utils import get_seven_days_read_data,get_today_hot_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) #获取该文件类型下前7天的阅读数
today_hot_data = get_today_hot_data(blog_content_type) #获取今天阅读数
return render(request,'home.html',{'dates':dates,'read_nums':read_nums,'today_hot_data':today_hot_data})
- 接下来打开templates/home.html文件,在里面添加相关html文件用于页面展示以及获取数据
templates/home.html
<!--今天24小时内的热门博客-->
<h3>今天热门点击</h3>
<ul>
{% for hot_data in today_hot_data %}
<li><a href='{% url 'blog_detail' hot_data.object_id %}' />{{ hot_data.content_object }}</a>
({{ hot_data.read_num }})</li>
{% empty %}
<li>今天暂时没有热门博客</li>
{% endfor %}
</ul>
注意: 1.上述的object_id和content_object字段均来自read_statistics/models.py里面ReadDetail模型里面的字段
2.object_id是获取文章的id;content_object是获取文章的对象
(如果文章模型blog在其模型里面使用了str方法返回标题,content_object即可以直接获取的是文章的标题)
页面显示效果:
2.昨天
read_statistics/utils.py
- 类似于今天的热点阅读,唯一不同就是查询的date数据是昨天时间即可。
- 在read_statistics/utils.py文件里新建今天阅读数量QuerySet的方法:get_yesterday_hot_data(),按照阅读量从多到少排序,取出数量最多的前7条数据
read_statistics/utils.py
def get_yesterday_hot_data(content_type):
'''获取今天24小时阅读数量-按照阅读量从多到少排序,取前7条数据'''
today = timezone.now().date() #当天的时间
yesterday=today-datetime.timedelta(days=1) #昨天的时间
read_details = ReadDetail.objects.filter(content_type=content_type,date=yesterday).order_by('-read_num')[:7]
return read_details
- 然后在yhsite/views.py里面引用get_yesterday_hot_data方法并且返回数据给前台home.html页面
yhsite/views.py
from django.shortcuts import render
from django.contrib.contenttypes.models import ContentType
from read_statistics.utils import get_seven_days_read_data,get_today_hot_data,get_yesterday_hot_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) # 获取该文件类型下前7天的阅读数
today_hot_data = get_today_hot_data(blog_content_type) # 获取今日24小时热门阅读点击
yesterday_hot_data = get_yesterday_hot_data(blog_content_type) # 获取昨天热门阅读点击
return render(request,'home.html',{'dates':dates,'read_nums':read_nums,
'today_hot_data':today_hot_data,
'yesterday_hot_data':yesterday_hot_data})
- 接下来打开templates/home.html文件,在里面添加相关html文件用于页面展示以及获取数据
templates/home.html
<h3>昨天热门点击</h3>
<ul>
{% for hot_data in yesterday_hot_data %}
<li><a href='{% url 'blog_detail' hot_data.object_id %}' />{{ hot_data.content_object }}</a>
({{ hot_data.read_num }})</li>
{% empty %}
<li>今天暂时没有热门博客</li>
{% endfor %}
</ul>
页面显示效果:
3.一周(7天)
7天的热门阅读稍微和前两个的获取方法不一样
- 首先在Django官网文档搜索contenttype关键字,搜索后打开第一个项目,如下图,然后接着找到反向泛型关系处,按照样例对blog/models.py进行修改添加,具体如图示标注
blog/models.py
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericRelation #7天内热门阅读点击
from ckeditor_uploader.fields import RichTextUploadingField
from read_statistics.models import ReadNumExpandMethod,ReadDetail
class Blog_type(models.Model):
type_name=models.CharField(max_length=15,verbose_name=u'分类名')
class Meta:
verbose_name='分类'
verbose_name_plural=verbose_name
def __str__(self):
return self.type_name
class Blog(models.Model,ReadNumExpandMethod):
title=models.CharField(max_length=50,verbose_name=u'标题')
blog_type=models.ForeignKey(Blog_type,on_delete=models.DO_NOTHING)
content=RichTextUploadingField()
author=models.ForeignKey(User,on_delete=models.DO_NOTHING,verbose_name='作者')
read_details = GenericRelation(ReadDetail) ##7天内热门阅读点击
created_time=models.DateTimeField(auto_now_add=True,verbose_name=u'创建时间')
last_update_time=models.DateTimeField(auto_now=True,verbose_name=u'修改时间')
is_delete=models.BooleanField(default=False,verbose_name=u'是否删除')
class Meta:
ordering=['-created_time']
verbose_name='博客'
verbose_name_plural=verbose_name
def __str__(self):
return self.title
mysite/views.py
-
在mysite/views.py创建get_7_days_hot_blogs()方法
引入需要的模块:
import datetime
from django.utils import timezone
from django.db.models import Sum
具体如图示:
mysite/views.py
import datetime
from django.utils import timezone
from django.db.models import Sum
from django.shortcuts import render
from django.contrib.contenttypes.models import ContentType
from read_statistics.utils import get_seven_days_read_data,get_today_hot_data,get_yesterday_hot_data
from blog.models import Blog
def get_7_days_hot_blogs():
'''获取7天内的热门阅读'''
today = timezone.now().date()
date = today - datetime.timedelta(days=7)
blogs = Blog.objects \
.filter(read_details__date__lt=today, read_details__date__gte=date) \
.values('id','title') \
.annotate(read_num_sum=Sum('read_details__read_num')) \
.order_by('-read_num_sum')[:7]
return blogs
def home(request):
blog_content_type=ContentType.objects.get_for_model(Blog) # 获取文件类型
dates,read_nums=get_seven_days_read_data(blog_content_type) # 获取该文件类型下前7天的阅读数
# 获取首页热门阅读
today_hot_data = get_today_hot_data(blog_content_type) # 获取今日24小时热门阅读点击
yesterday_hot_data = get_yesterday_hot_data(blog_content_type) # 获取昨天热门阅读点击
hot_blogs_for_7_days = get_7_days_hot_blogs() #获取7天内热门阅读点击
return render(request,'home.html',{'dates':dates,'read_nums':read_nums,
'today_hot_data':today_hot_data,
'yesterday_hot_data':yesterday_hot_data,
'hot_blogs_for_7_days':hot_blogs_for_7_days})
templates/home.html
<h3>7日内热门点击</h3>
<ul>
{% for hot_blog in hot_blogs_for_7_days %}
<li><a href='{% url 'blog_detail' hot_blog.id %}' />{{ hot_blog.title }}</a>
({{ hot_blog.read_num_sum }})</li>
{% empty %}
<li>7天内暂时没有热门博客</li>
{% endfor %}
</ul>
页面显示效果:
4.一月(30天)
跟7天热门阅读的方法类似,只需要将时间date = today - datetime.timedelta(days=7)
的days-7改成对应天数即可:days=30,其他天数一样,修改天数即可
def get_30_days_hot_blogs():
'''获取7天内的热门阅读'''
today = timezone.now().date()
date = today - datetime.timedelta(days=30)
blogs = Blog.objects \
.filter(read_details__date__lt=today, read_details__date__gte=date) \
.values('id','title') \
.annotate(read_num_sum=Sum('read_details__read_num')) \
.order_by('-read_num_sum')[:7]
return blogs
页面展示代码按照7天的来写即可,这里不再赘述。
二、缓存提速
数据库的缓存
1.设置并创建缓存表
在Django官网查找缓存相关文档的数据库缓存,如下图:
Django官网-数据库缓存
1.将标注的内容拷贝到项目的setting.py文件里面
2.执行创建缓存标的命令
python manage.py createcachetable
2.访问缓存
1.引入缓存模块
将from django.core.cache import cache
引入到mysite/views.py文件里面
2.根据访问缓存基本方法获取7天热门博客文章缓存数据
打开mysite/views.py文件,在里面写如下创建以及获取缓存的代码:
创建缓存,缓存时间为60分钟,如果没有缓存,先创建,刷新页面后台会打印print('cache')
语句;如果已有缓存,而且缓存还没有超过缓存时间,即还没失效,刷新页面后台会打印print('use cache')
语句
import datetime
from django.utils import timezone
from django.db.models import Sum
from django.shortcuts import render
from django.core.cache import cache #缓存
from django.contrib.contenttypes.models import ContentType
from read_statistics.utils import get_seven_days_read_data,get_today_hot_data,get_yesterday_hot_data
from blog.models import Blog
def get_7_days_hot_blogs():
'''获取7天内的热门阅读'''
today = timezone.now().date()
date = today - datetime.timedelta(days=7)
blogs = Blog.objects \
.filter(read_details__date__lt=today, read_details__date__gte=date) \
.values('id','title') \
.annotate(read_num_sum=Sum('read_details__read_num')) \
.order_by('-read_num_sum')[:7]
return blogs
def home(request):
blog_content_type=ContentType.objects.get_for_model(Blog) # 获取文件类型
dates,read_nums=get_seven_days_read_data(blog_content_type) # 获取该文件类型下前7天的阅读数
# 获取7天热门博客的缓存数据
hot_blogs_for_7_days = cache.get('hot_blogs_for_7_days')
if hot_blogs_for_7_days is None:
hot_blogs_for_7_days = get_7_days_hot_blogs()
cache.set('hot_blogs_for_7_days', hot_blogs_for_7_days, 3600)
print('cache')
else:
print('use cache')
# 获取首页热门阅读
today_hot_data = get_today_hot_data(blog_content_type) # 获取今日24小时热门阅读点击
yesterday_hot_data = get_yesterday_hot_data(blog_content_type) # 获取昨天热门阅读点击
hot_blogs_for_7_days = hot_blogs_for_7_days #获取7天内热门阅读点击
return render(request,'home.html',{'dates':dates,'read_nums':read_nums,
'today_hot_data':today_hot_data,
'yesterday_hot_data':yesterday_hot_data,
'hot_blogs_for_7_days':hot_blogs_for_7_days})
三、美化页面
1.home.html页面的调整
将所有的热点阅读都放到一个<div class='hot-data'>...</div>
div容器里面,如下图:
templates/home.html
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}我的网站|首页{% endblock %}
{% block header_extends %}
<link rel="stylesheet" type="text/css" href="{% static 'css/home.css' %}">
<script src="http://cdn.hcharts.cn/highcharts/highcharts.js"></script>
{% endblock %}
{% block nav_home_active%}active{% endblock %}
{% block content %}
<h3 class="home-content">欢迎访问我的网站,随便看</h3>
<!-- 图表容器 DOM -->
<div id="container"></div>
<div class='hot-data'>
<h3>24小时热门点击</h3>
<ul>
{% for hot_data in today_hot_data %}
<li><a href='{% url 'blog_detail' hot_data.object_id %}' />{{ hot_data.content_object }}</a>
({{ hot_data.read_num }})</li>
{% empty %}
<li>今天暂时没有热门博客</li>
{% endfor %}
</ul>
</div>
<div class='hot-data'>
<h3>昨天热门点击</h3>
<ul>
{% for hot_data in yesterday_hot_data %}
<li><a href='{% url 'blog_detail' hot_data.object_id %}' />{{ hot_data.content_object }}</a>
({{ hot_data.read_num }})</li>
{% empty %}
<li>昨天暂时没有热门博客</li>
{% endfor %}
</ul>
</div>
<div class='hot-data'>
<h3>7日内热门点击</h3>
<ul>
{% for hot_blog in hot_blogs_for_7_days %}
<li><a href='{% url 'blog_detail' hot_blog.id %}' />{{ hot_blog.title }}</a>
({{ hot_blog.read_num_sum }})</li>
{% empty %}
<li>7天内暂时没有热门博客</li>
{% endfor %}
</ul>
</div>
<script>
// 图表配置
var options = {
chart: { type: 'line' },
title: { text: null },
xAxis: {
categories: {{ dates|safe }}, // x 轴分类
tickmarkPlacement: 'on',
title: { text: '前7日阅读量变化'},
},
yAxis: {
title: { text: null },
labels:{ enabled: false },
gridLineDashStyle: 'Dash',
},
series: [{ // 数据列
name: '阅读量', // 数据列名
data: {{ read_nums }} // 数据
}],
plotOptions: {
line: {
dataLabels: {
enabled: true
}
}
},
legend: { enabled: false },
credits: { enabled: false },
};
// 图表初始化函数
var chart = Highcharts.chart('container', options);
</script>
{% endblock %}
2.home.css样式的添加
static/css/home.html
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;
}
div.hot-data {
text-align: center;
margin-top: 2em;
}
页面展示样式: