一. 博客阅读次数排行
博客被阅读的次数越多,代表该博客越热门。通常按照时间的长短来进行分类统计:
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)
注明:学习资料来自“再敲一行代码的个人空间”以及“杨仕航的博客”