前言
- 现实的需求是, 想要算出前七天热门的博客是哪些, 并计算数量
- 我已经写好一个contenttypes模型用与计算每天博客的阅读次数
class ReadDetail(models.Model):
"""
浏览量按日统计
"""
date = models.DateField(default=timezone.now, verbose_name='日期')
read_num = models.IntegerField(default=0, verbose_name='阅读次数')
content_type = models.ForeignKey(ContentType, on_delete=models.DO_NOTHING, verbose_name='类型')
object_id = models.PositiveIntegerField(verbose_name='博客id')
content_object = GenericForeignKey('content_type', 'object_id')
# 如果这些字段名为“content_type”和“object_id”,则可以省略
def show_content(self):
return "标题: %s" %(self.content_object.title)
class Meta:
verbose_name = "访问量统计"
verbose_name_plural = verbose_name
反向通用关系
类GenericRelation
from django.contrib.contenttypes.fields import GenericRelation
class Blog(models.Model, ReadNumExpandMethod):
read_details = GenericRelation(ReadDetail)
title = models.CharField(max_length=50, verbose_name="标题")
- Blog每个实例都有一个read_details属性,可以用来检索它们的关联ReadDetail
def get_7days_hot_blog():
"""
获取前七天热门博客
:return:
"""
today = timezone.datetime.now()
date = today - datetime.timedelta(days=7)
blog = Blog.objects.filter(read_details__date__gte=date, read_details__date__lt=today) \
.values('id', 'title',).annotate(read_num_sum = Sum('read_details__read_num')) \
.order_by('-read_num_sum')
return blog[:7]
values: 返回一个QuerySet在用作iterable时返回字典而不是模型实例。
每个字典代表一个对象,其中的键对应于模型对象的属性名称。(官方解释)
<QuerySet [{'id': 33, 'title': 'Django restframework'},
{'id': 23, 'title': 'for 20'}, {'id': 20, 'title': 'for 17'},
{'id': 4, 'title': 'for 1'}, {'id': 3, 'title': 'for 29'},
{'id': 1, 'title': '学习'}, {'id': 1, 'title': '学习'}]>
annotate :每个参数都是一个注释,将被添加到QuerySet返回的每个对象中。
<QuerySet [{'id': 33, 'title': 'Django restframework', 'read_num_sum': 1},
{'id': 23, 'title': 'for 20', 'read_num_sum': 7},
{'id': 20, 'title': 'for 17', 'read_num_sum': 1},
{'id': 4, 'title': 'for 1', 'read_num_sum': 6},
{'id': 3, 'title': 'for 29', 'read_num_sum': 5},
{'id': 1, 'title': '学习', 'read_num_sum': 2}]>