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>