[Django学习] Django基础(12)_热门博客排行

一. 博客阅读次数排行

  博客被阅读的次数越多,代表该博客越热门。通常按照时间的长短来进行分类统计:

  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)

注明:学习资料来自“再敲一行代码的个人空间”以及“杨仕航的博客”

原文地址:https://www.cnblogs.com/AngryZe/p/9332575.html