获取按最近条目排序的主题
Get Topics ordered by recent Entries
假设我有模型:
class Entry(models.Model):
topic = models.ForeignKey(Topic)
date_created = models.DateTimeField()
class Topic(models.Model):
title = models.CharField(max_length=100)
我想创建一个 returns 主题的查询集,其中包含创建日期在过去 24 小时内的条目。主题应排序,以便第一个主题具有最新条目。
我用 Postgres 试过了,但是顺序丢失了:
Topic.objects.filter(entry_set__date_created__gte=timezone.now() - datetime.timedelta(hours=24))\
.order_by('entry_set__topic', '-entry_set__date_created').distinct('entry_set__topic')
我找到了 a solution to a similar problem 但它是用原始 sql 编写的,我无法将它转换为 django-orm。
更新:
所以这是一个可以在 2 个查询集中实现我想要的效果的工作解决方案(我正在寻找可以在一个查询集中实现此目的的解决方案):
desired_date = timezone.now() - datetime.timedelta(hours=24)
distinct_ids = Topic.objects.filter(entries__date_created__gte=desired_date).distinct().values_list('id', flat=True)
ordered_qs = Topic.objects.filter(id__in=distinct_ids).annotate(lts=Max("entries__date_created")).order_by('-lts')
已编辑:
desired_date = timezone.now() - datetime.timedelta(hours=24)
topics=Entry.objects.filter(date_created__gte=desired_date).order_by('date_created').values_list('topic', flat=True).distinct()
可以通过提供模型元数据对主题进行排序,以便第一个主题具有最新条目。
此处 -date_added
将根据您的意愿对主题进行排序。使用内部 class Meta 为您的模型提供元数据,如下所示:
class Topic(models.Model):
title = models.CharField(max_length=100)
class Meta:
ordering = ('-date_added')
def __unicode__(self):
return str(self.name)
模型元数据是“任何不是字段的东西”,例如排序选项 (ordering
)、数据库 table 名称 (db_table
) 或人类可读的单数和复数名称(verbose_name
和 verbose_name_plural
)。 None 是必需的,向模型添加 class 元是完全可选的。
此 official django documentation 解释了您可以为模型提供的所有可能的元数据选项
你试过吗?
from datetime import datetime, timedelta
from django.db.models import Max
latest_entry_time = dict(last_entry_dt=Max('entries__date_created'))
last_24_hour_filter = dict(entries__date_created__gte=datetime.utcnow() - timedelta(hours=24))
<b>result = Topic.objects.annotate(**latest_entry_time).filter(**last_24_hour_filter).order_by('-last_entry_dt')</b>
说明
latest_entry_time
: 用来标注最新的date_created
值到 每个 Topic
对象
last_24_hour_filter
:用于过滤掉Entry实例
.order_by('-last_entry_dt')
:因为我们确实有 注释字段 (请参阅解释 1),我们可以在这里使用它。
希望它清楚!!
假设我有模型:
class Entry(models.Model):
topic = models.ForeignKey(Topic)
date_created = models.DateTimeField()
class Topic(models.Model):
title = models.CharField(max_length=100)
我想创建一个 returns 主题的查询集,其中包含创建日期在过去 24 小时内的条目。主题应排序,以便第一个主题具有最新条目。
我用 Postgres 试过了,但是顺序丢失了:
Topic.objects.filter(entry_set__date_created__gte=timezone.now() - datetime.timedelta(hours=24))\
.order_by('entry_set__topic', '-entry_set__date_created').distinct('entry_set__topic')
我找到了 a solution to a similar problem 但它是用原始 sql 编写的,我无法将它转换为 django-orm。
更新:
所以这是一个可以在 2 个查询集中实现我想要的效果的工作解决方案(我正在寻找可以在一个查询集中实现此目的的解决方案):
desired_date = timezone.now() - datetime.timedelta(hours=24)
distinct_ids = Topic.objects.filter(entries__date_created__gte=desired_date).distinct().values_list('id', flat=True)
ordered_qs = Topic.objects.filter(id__in=distinct_ids).annotate(lts=Max("entries__date_created")).order_by('-lts')
已编辑:
desired_date = timezone.now() - datetime.timedelta(hours=24)
topics=Entry.objects.filter(date_created__gte=desired_date).order_by('date_created').values_list('topic', flat=True).distinct()
可以通过提供模型元数据对主题进行排序,以便第一个主题具有最新条目。
此处 -date_added
将根据您的意愿对主题进行排序。使用内部 class Meta 为您的模型提供元数据,如下所示:
class Topic(models.Model):
title = models.CharField(max_length=100)
class Meta:
ordering = ('-date_added')
def __unicode__(self):
return str(self.name)
模型元数据是“任何不是字段的东西”,例如排序选项 (ordering
)、数据库 table 名称 (db_table
) 或人类可读的单数和复数名称(verbose_name
和 verbose_name_plural
)。 None 是必需的,向模型添加 class 元是完全可选的。
此 official django documentation 解释了您可以为模型提供的所有可能的元数据选项
你试过吗?
from datetime import datetime, timedelta
from django.db.models import Max
latest_entry_time = dict(last_entry_dt=Max('entries__date_created'))
last_24_hour_filter = dict(entries__date_created__gte=datetime.utcnow() - timedelta(hours=24))
<b>result = Topic.objects.annotate(**latest_entry_time).filter(**last_24_hour_filter).order_by('-last_entry_dt')</b>
说明
latest_entry_time
: 用来标注最新的date_created
值到 每个Topic
对象last_24_hour_filter
:用于过滤掉Entry实例.order_by('-last_entry_dt')
:因为我们确实有 注释字段 (请参阅解释 1),我们可以在这里使用它。
希望它清楚!!