Django 获取按最近条目排序的主题
假设我有模型:Django 获取按最近条目排序的主题,django,django-models,django-queryset,django-orm,Django,Django Models,Django Queryset,Django Orm,假设我有模型: class Entry(models.Model): topic = models.ForeignKey(Topic) date_created = models.DateTimeField() class Topic(models.Model): title = models.CharField(max_length=100) 我想创建一个queryset,它返回的主题包含创建日期在过去24小时内的条目。主题应按顺序排列,以便第一个主题具有最新条目
class Entry(models.Model):
topic = models.ForeignKey(Topic)
date_created = models.DateTimeField()
class Topic(models.Model):
title = models.CharField(max_length=100)
我想创建一个queryset,它返回的主题包含创建日期在过去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')
我找到了,但它是用原始sql编写的,我无法将其转换为django orm
更新:
因此,这里有一个工作解决方案,可以在2个查询集中实现我想要的(我正在寻找一个可以在一个查询集中实现这一点的解决方案):
编辑:
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\u added
将根据您的意愿对您的主题进行排序。使用内部的类Meta提供模型元数据,如下所示:
class Topic(models.Model):
title = models.CharField(max_length=100)
class Meta:
ordering = ('-date_added')
def __unicode__(self):
return str(self.name)
模型元数据是“非字段的任何内容”,例如排序选项(ordering
)、数据库表名称(db\u table
),或人类可读的单数和复数名称(verbose\u name
和verbose\u name\u复数
)。不需要,向模型添加类Meta是完全可选的
这解释了您可以为模型提供的所有可能的元数据选项您尝试过吗
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))
result = Topic.objects.annotate(**latest_entry_time).filter(**last_24_hour_filter).order_by('-last_entry_dt')
从datetime导入datetime,timedelta
从django.db.models导入最大值
最新输入时间=dict(最后输入日期=最大值('entries\u date\u created'))
last_24_hour_filter=dict(条目_date_created_gte=datetime.utcnow()-timedelta(小时=24))
结果=Topic.objects.annotate(**最新条目\时间)。筛选(**最后24小时\筛选)。排序依据('-last\条目\时间')
解释
latest\u entry\u time
:用于在每个主题
对象中注释最新创建的日期
值last\u 24h\u filter
:用于筛选出条目实例.order\u by('-last\u entry\u dt')
:由于我们有注释字段(请参见说明1),我们可以在这里使用它。希望它清楚李>
删除第一个参数将创建重复的参数。我想使用distinct删除这些参数,但distinct参数必须与第一个参数相同。请尝试重新排序您的修饰符。dotopic.objects.filter(entry\u set\u date\u created\u gte=timezone.now()-datetime.timedelta(hours=24)).distinct('entry\u set\u Topic').order\u by('-entry\u set\u date\u created')产生相同的结果,它们可能在后面转换为相同的SQL。据我所知,没有办法使不同的对象有序。请使用两个单独的查询。具有中间id列表。我更新了我的初始注释。在Orderedq中,使用entry_set_date_created从其他主题创建对象(它可能会考虑所有条目),但可以解决:“Topic.objects.filter(id__In=distinct_id)。annotate(lts=Max(“entries_date_created”)。order_by('-lts')”。然而,这并不能回答我的问题,因为我只需要一个查询,这将不起作用,因为元数据不考虑条目的创建日期,而是;它考虑主题创建日期。将元数据选项添加到条目模型具有与order_相同的效果。太好了,我从没想到会这么容易!但我有一个问题:prev_24_hour_topics=Topic.objects.annotation(last_entry_dt=Max('entries_date_created')).filter(entries_date_created_gte=datetime.utcnow()-timedelta(hours=24)).order_by('-last_entry_dt)有什么不同吗?没有,我的意思是说你使用字典解包只是为了可读性,还是它有任何特定的功能?
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))
result = Topic.objects.annotate(**latest_entry_time).filter(**last_24_hour_filter).order_by('-last_entry_dt')