Django 查询获取最后 n 条记录

假设我正在实现一个消息流,记录按 ID 升序排序,每次获取请求,我只允许获取最新的10条记录。

我试过:

Messages.objects.filter(since=since)[:-10]

我在说不支持负索引时犯了一个错误。

我当前的工作是按降序排序 ID,然后运行:

Messages.objects.filter(since=since)[:10]

但这需要前端再次反转顺序。

我的问题是,有没有一种优雅的方式?

109639 次浏览

You can pass your queryset to reversed:

last_ten = Messages.objects.filter(since=since).order_by('-id')[:10]
last_ten_in_ascending_order = reversed(last_ten)

Or use [::-1] instead of reversed:

last_ten = Messages.objects.filter(since=since).order_by('-id')[:10][::-1]

@ron_g:

Above solution uses list comprehension twice (first to slice to 10, then to reverse). You can do it as one operation, it's 9x faster.

last_ten = Messages.objects.filter(since=since).order_by('-id')[:10:-1]

If you want last X records sorted in descending order by id , Then I don't think you need since filter

last_ten = Messages.objects.all().order_by('-id')[:10]

Using -id will sort in descending order. Hope this was helpful !!

In response to ron_g's comment in Omid Raha's answer:

Consider the case where there are less than 10 records in the list:

Note that this approach

list[:10:-1]

will return an empty list, in contrast to

list[:10][::-1]

which will return all the records in the list, if the total records are less than 10.

I wanted to retrieve the last 25 messages and solved this problem in the following way

#models.py


class Meta:
ordering = ['created']
#views.py


message1 = []
for message in pm_messages.objects.filter(room=room_name).reverse()[0:25]:
message1.append(message)
messagess = message1.reverse()

you can convert the queryset to a list and select the last n elements normally

messages = list(Messages.objects.filter(since=since))
messages = oldMessageis[-n:len(oldMessageis)]