如何在不读取 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]
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]