如何在不读取 Django 中的所有对象的情况下从数据库中获取一些最后的对象?

how can I get some last objects from DB without reading all of the objects in Django?

Django 中有一些函数可以帮助您获取第一条或最后一条记录,例如first()earliest()last()latest()。我正在寻找的是一个函数,它可以在不读取所有数据的情况下获取一些最后的对象。例如,像这样获取最后 3 个对象:

last_three_objects = my_model.objects.get_last(count=3)

PS:我知道可以这样获取:

last_three_objects = my_model.objects.all()[:3]

或:

last_three_objects = my_model.objects.all().order_by('-datetime')[:3]

但我认为它会从数据库中读取所有 my_model 数据并且效率不高!有什么想法吗?

创建数据时间模型

created = models.DateTimeField(auto_now_add=True, null=True)

在视图中获取创建的字段

course = Course.objects.all().order_by('-created')[:6]

minus表示数据库中的最新数据,借助切片我们得到最新的六项。

But I think it will read all of my_model data from DB and it's not efficient! Any thoughts?

不正确QuerySet们很懒惰。这意味着 .all() 不会被评估,除非你 "consume" 它,例如通过迭代它,或者通过调用 len(…)str(…) 它。

即使你切片,它也不会立即进行查询,你得到一个QuerySet承诺需要时进行查询。所以:

latest_three_objects = my_model.objects.all()[:3]

甚至不会进行查询,除非您对其进行迭代,在这种情况下,它将查询:

SELECT my_model.*
FROM my_model
<b>LIMIT 3</b>

例如,您可以通过以下方式检查查询:

<b>print(</b>my_model.objects.all()[:3]<b>.query)</b>

例如在 Django shell 中。

但是不是return最新的三个元素,它可以return你模型的任何三个元素。如果想要主键最大的元素,可以使用:

my_model.objects<b>.order_by('-pk')</b>[:3]

此外,按主键排序不是一个好主意,因为您无法控制主键的分布方式,这是数据库的责任。你可以更好地制作一个存储时间戳的字段:

class MyModel(models.Model):
    timestamp = models.DateTimeField(<b>auto_now_add=True, db_index=True</b>)

然后按最新时间戳检索元素:

my_model.objects<b>.order_by('-timestamp')</b>[:3]