21、热门阅读博客排行及缓存提速
1、利用阅读量数据排行
- 1、24小时内 ——> 今天数据统计
- 2、昨日 ——> 昨天数据统计
- 3、一周
- 4、30天
我们先来完成第一个功能:24小时内(今日)数据统计
我们可以考虑写到阅读计数 read_statistics 这个app里面
修改 read_statistics 下的 utils.py 如下:
# 传入一个博客类型进来,筛选出日期和博客类型,然后根据阅读数量进行倒序排序
def get_today_hot_data(content_type):
today = timezone.now().date()
read_details = ReadDetail.objects.filter(content_type=content_type, date=today).order_by('-read_num')
return read_details
修改全局 mysite/views.py如下:
修改首页 home.html如下:
<!--今天24小时内的热门博客-->
<h3>今天热门点击</h3>
<ul>
{% for hot_data in today_hot_data %}
<li>{{ hot_data.object_id }}({{ hot_data.read_num }})</li>
{% empty %}
<li>今天暂时没有热门内容</li>
{% endfor %}
</ul>
刷新页面:
我们点击一下(让今天有博客阅读量),然后再刷新首页页面
下一步我们就要把显示热门博客的id改为显示热门博客的标题,并且可以点击链接
修改home.html如下:
<li><a href="{% url 'blog_detail' hot_data.content_object.pk %}">{{ hot_data.object_id }}</a>({{ hot_data.read_num }})</li>
接下来我们完成第二个功能:昨天数据统计
结构和上面的一致
修改utils.py如下:
# 昨天的数据统计
def get_yesterday_hot_data(content_type):
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')
return read_details
修改views.py如下:
修改home.html:
刷新页面:
这里,如果有多条热门博客,不可能在首页全部显示出来,所以最好只显示前七篇 诸如此类
可以修改utils.py如下:
接下来我们完成第三个功能:一周数据统计
修改utils.py如下:
# 7天的数据统计
def get_7_days_hot_data(content_type):
today = timezone.now().date()
date = today - datetime.timedelta(days=7)
# date__lt=today,date__gte=date:小于今天,大于等于前7天。然后偶按照博客id分组统计阅读量,即 分组+求和
# 这个values方法是将查询集变成一个迭代器,迭代器里元素是字典,后面指定参数就可以取出每项的键值对,之后进行求和
# values对应实现分组,然后annotate实现求和
read_details = ReadDetail.objects \
.filter(content_type=content_type, date__lt=today,date__gte=date) \
.values('content_type', 'object_id') \
.annotate(read_num_sum=Sum('read_num')) \
.order_by('-read_num')
return read_details[:7]
修改views.py如下:
修改home.html如下:
刷新页面,可以看到会出错。
这里跟utils.py里面我们写的方法有关,这里返回是ReadDetail这个模型对应的东西,那有没有一种方法直接返回博客对应模型的记录,而不用走ReadDetail。我们得到的数据虽然说可以进一步进行遍历处理等等, 但还是有点麻烦,那么这里可以用到ContentType另外一个东西,叫做反向泛型关系
修改blog/models.py如下:
保存后,也可以在shell模式下演示下:
这个全部明细记录可以取得到,我们就可以通过Blog查询
进一步进行处理,我们修改mysite/views.py如下:
保存,同样我们可以在shell模式下进行演示:
然后对其进行分组统计
相应的,修改views.py如下:(return blogs后面记得加[:7])
# 7天的数据统计
def get_7_days_hot_blogs():
today = timezone.now().date()
date = today - datetime.timedelta(days=7)
# date__lt=today,date__gte=date:小于今天,大于等于前7天。然后偶按照博客id分组统计阅读量,即 分组+求和
# 这个values方法是将查询集变成一个迭代器,迭代器里元素是字典,后面指定参数就可以取出每项的键值对,之后进行求和
# values对应实现分组,然后annotate实现求和
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')
return blogs
删除utils.py里面对应的7天数据统计的方法函数
对应的,修改home.html如下:
刷新页面:
第四个功能:获取30天内的数据统计(同理7天的)
2、每次都计算,耗时
- 策略:缓存数据,不用每次都计算
- 分为:
- 内存缓存:Memcached、Redis
- 数据库缓存
- 文件缓存
其中,数据库缓存就是存到django所用的数据库里面,可以查看django官方文档:
settings.py文件修改如下:
# 缓存设置
CACHES= {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table', # 缓存的表名(也可以自己定义)
}
}
然后在命令行创建缓存表python manage.py createcachetable
这个缓存,不是客户端不是我们本地浏览器的缓存,它指的是服务器我们后台的一个缓存
接着,我们修改views.py如下:
# 获取7天热门博客的缓存数据
hot_blogs_for_7_days = cache.get('hot_blogs_for_7_days')
if hot_blogs_for_7_days is None: # 如果是None,则需要进行计算得到缓存数据,这个计算就是get_7_days_hot_blogs()方法
hot_blogs_for_7_days = get_7_days_hot_blogs() # 将这个方法写到变量里面,然后进行缓存
cache.set('hot_blogs_for_7_days', hot_blogs_for_7_days, 3600) # 键值,缓存内容,有效期(这里设置为1h)
print('calc')
else:
print('use cache')
保存之后,启动服务,刷新页面三次,可以看到第一次刷新是计算得到的数据,第二次和第三次刷新是使用的缓存,在有效期内的缓存
接下来一步,就是将热门博客的页面展示做的好看一些
先在home.html里面标签添加几个class属性名称
然后修改home.css如下:
div.hot-data {
text-align: center;
margin-top: 2em;
}
ul {
font-size: 1.5em;
}