获取按最近条目排序的主题

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_nameverbose_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>

说明

  1. latest_entry_time : 用来标注最新的date_created 值到 每个 Topic 对象
  2. last_24_hour_filter :用于过滤掉Entry实例
  3. .order_by('-last_entry_dt') :因为我们确实有 注释字段 (请参阅解释 1),我们可以在这里使用它。

    希望它清楚!!