热门博客阅读及缓存提速

1.利用阅读量数据排行

1>24小时内——>今天数据统计

2>昨日——>昨天数据统计

3>一周

4>30天

今天和昨天比较好做,获取今天和昨天的日期,根据传入的content_type和日期筛选出符合的记录,并按阅读次数倒序排序,返回ReadDetail的查询集

def get_today_hot_date(content_type):
today = timezone.now().date()
read_details = ReadDetail.objects.filter(content_type=content_type,date=today).order_by('-read_num')
return read_details[:7]

def get_yesterday_hot_date(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[:7]
views页面调用该方法
context['today_hot_data'] = get_today_hot_date(content_type=blog_content_type)
context['yesterday_hot_data'] = get_yesterday_hot_date(content_type=blog_content_type)

前端页面展示,ReadDetail对象.content_object可以访问到对应的博客,ReadDetail对象.read_num是当天阅读数量
<h3>今天热门博客</h3>
<ul>
{% for hot_data in today_hot_data %}
<li><a href="{% url 'blog_detail' hot_data.content_object.pk %}">{{ hot_data.content_object.title }}</a>({{ hot_data.read_num }})</li>
{% empty %}
<li>今天暂时没有热门博客</li>
{% endfor %}

</ul>
<h3>昨天热门博客</h3>
<ul>
{% for hot_data in yesterday_hot_data %}
<li><a href="{% url 'blog_detail' hot_data.content_object.pk %}">{{ hot_data.content_object.title }}</a>
({{ hot_data.read_num }})</li>
{% empty %}
<li>昨天暂时没有热门博客</li>
{% endfor %}

</ul>

有时间范围的热门博客统计使用反向通用关系比较好在前端显示
在Blog模型增加新字段,设置反向通用关系到ReadDetails
read_details = GenericRelation(ReadDetail)
此时通过shell探究其功能

>>> from blog.models import Blog
>>> blog = Blog.objects.first()
>>> blog
<Blog: <Blog: for 30>>
>>> blog.read_details
<django.contrib.contenttypes.fields.create_generic_related_manager.<locals>.GenericRelatedObjectManager object at 0x000001BF9CB5D3C8>
>>> blog.read_details.all()
<QuerySet [<ReadDetail: ReadDetail object (1)>, <ReadDetail: ReadDetail object (3)>, <ReadDetail: ReadDetail object (4)>]>

通过Blog对象可以访问到ReadDetail,之后进行分组求和

>>> from blog.models import Blog
>>> import datetime
>>> from django.utils import timezone
>>> today = timezone.now().date()
>>> date = today - datetime.timedelta(days=7)
>>> Blog.objects.filter(read_details__date__lt=today, read_details__date__gte=date)
<QuerySet [<Blog: <Blog: for 30>>, <Blog: <Blog: for 30>>, <Blog: <Blog: for 29>>]>
>>> Blog.objects.filter(read_details__date__lt=today, read_details__date__gte=date).values('id','title')
<QuerySet [{'id': 36, 'title': 'for 30'}, {'id': 36, 'title': 'for 30'}, {'id': 35, 'title': 'for 29'}]>
>>> from django.db.models import Sum
>>> 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'))
<QuerySet [{'id': 36, 'title': 'for 30', 'read_num_sum': 9}, {'id': 35, 'title': 'for 29', 'read_num_sum': 2}]>

在主views中写获取7天热门博客的方法

def get_7_days_hot_blogs():
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')
return blogs[:7]
values()返回QuerySet用作迭代器时返回的字典,而不是模型实例
annotate()每个参数annotate()都是一个注释,该注释将添加到QuerySet返回的对象中。

前端调用
    <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>昨天暂时没有热门博客</li>
{% endfor %}

</ul>

2.每次都计算,耗时
策略:缓存数据,不用每次都计算
如昨天和前7天的数据是固定好的,我们不用每次都计算,我们只需要在一个地方把它缓存下来,隔一定时间更新一下就行,如隔一天或一小时。
内存缓存:Memcached、Redis
数据库缓存:
文件缓存:
下面用Django的数据库缓存
1>在settins中设置
#缓存设置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table',
}
}
2>创建缓存表
python manage.py createcachetable
3>缓存基本用法 获取缓存,如果缓存不存在则返回None,立即设置缓存,键 值 时间。
from django.core.cache import cache
#获取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)
context = {}
context['hot_blogs_for_7_days'] = hot_blogs_for_7_days
return render(request,'home.html',context)


 
原文地址:https://www.cnblogs.com/lag1/p/13844149.html