一. 博客阅读次数排行
博客被阅读的次数越多,代表该博客越热门。通常按照时间的长短来进行分类统计:
1. 今日热门
2. 七天热门
3. 三十天热门
二. 表现样式

具体html代码(以今天热门点击为例)为:
<!-- 24小时以内热帖 -->
<h3>今天热门点击</h3>
<ul>
{% for hot_data in today_hot_data %}
<li><a href="{% url 'blog_detail' hot_data.id %}">{{ hot_data.title }}</a>({{hot_data.read_num_sum}})</li>
{% empty %}
<li>今天暂时没有热门博客</li>
{% endfor %}
</ul>
从代码中可知,需要具体某一片博客的id(hot_data.id),title(hot_data.title)以及该博客的阅读计数统计(hot_data.read_num_sum)。
三. 具体思路
1. 获取今日的时间
today = timezone.now().date()
2. 计算出要分类的时间
date = today-datetime.timedelta(days=daynum)
3. 在blog.models.Blog中添加contenttypes.field.GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericRelation
from blogstatistics.models import ReadNum,ReadNumExpandMethod, ReadDetailNum
from ckeditor_uploader.fields import RichTextUploadingField
class Blog(models.Model, ReadNumExpandMethod):
# ...其他内容省略
# GenericRelation:可以让Blog使用与其指定关联的ReadDtailNum中的内容
read_details = GenericRelation(ReadDetailNum)
# ...其他内容神略
4. 获取时间条件内所有博客
# blog.models.Blog中的read_details=GenericRelation(ReadDetailNum) # Blog可以使用ReadDetailNum中的date属性 >>> blogs = Blog.objects.filter(read_details__date__lte=today,read_details__date__gte=sevendate) >>> blogs <QuerySet [<Blog: <BLog: for 29>>, <Blog: <BLog: for 27>>, <Blog: <BLog: for 26>>, <Blog: <BLog: for 24>>, <Blog: <BLog: for 24>>]>
5. 提取具体博客的id和title(使用QuerySet中的values()方法)
>>> blogs.values('id','title')
<QuerySet [{'id': 32, 'title': 'for 29'}, {'id': 30, 'title': 'for 27'},
{'id': 29, 'title': 'for 26'}, {'id': 27, 'title': 'for 24'}, {'id': 27, 'title': 'for 24'}]>
6. 对查询出的QuerySet进行统计(使用QuerySet中的annotate()方法)
>>> from django.db.models import Sum
#同样,BGenericRelation让涉及Blog的所有对象都可以使用ReadDetailNum中的字段
>>> blogs.values('id','title').annotate(Sum('read_details__read_num'))
<QuerySet [
{'id': 32, 'title': 'for 29', 'read_details__read_num__sum': 1},
{'id': 30, 'title': 'for 27', 'read_details__read_num__sum': 1},
{'id': 29, 'title': 'for 26', 'read_details__read_num__sum': 1},
{'id': 27, 'title': 'for 24', 'read_details__read_num__sum': 4}]>
7. 封装成方法
def get_blogs_hot_data(daynum):
today = timezone.now().date()
date = today-datetime.timedelta(days=daynum)
blogs = Blog.objects
.filter(read_details__date__lte=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]
8. views.py中调用该方法
from django.shortcuts import render_to_response
from django.contrib.contenttypes.models import ContentType
from blogstatistics.utils import get_seven_days_read_data, get_blogs_hot_data
from blog.models import Blog
def home(request):
ct = ContentType.objects.get_for_model(Blog)
date_list,read_nums = get_seven_days_read_data(ct)
context = {}
context['date_list']=date_list
context['read_nums'] = read_nums
context['today_hot_data'] = get_blogs_hot_data(0)
context['sevenday_hot_data'] = get_blogs_hot_data(7)
context['month_hot_data'] = get_blogs_hot_data(30)
return render_to_response('home.html',context)
注明:学习资料来自“再敲一行代码的个人空间”以及“杨仕航的博客”