在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
从DB中获取数据,但效率不高! 有什么想法吗?
但我认为它会读取所有的
my_model
从DB中获取数据,但效率不高! 有什么想法吗?
那是 错. QuerySet
的是懒惰。这意味着 .all()
不会被评估,除非你 "消耗 "它,例如通过迭代它,或通过调用 len(…)
或 str(…)
上的。
即使你切片,它也不会立即进行查询,你获得的是一个 QuerySet
该 承诺 来进行查询,如果你需要的话。所以。
latest_three_objects = my_model.objects.all()[:3]
甚至不会进行查询,除非你对它进行迭代,在这种情况下,它将用查询。
SELECT my_model.*
FROM my_model
LIMIT 3
例如,你可以通过在Django shell中编写:
print(my_model.objects.all()[:3].query)
例如,你可以在Django shell中写下:来检查查询。
然而这将 不 返回最新的三个元素,它可以返回你的模型的任何三个元素。如果你想要拥有最大主键的元素,你可以使用。
my_model.objects.order_by('-pk')[:3]
此外,按主键排序并不是一个好主意,因为你无法控制主键的分布,那是数据库的责任。你最好可以做一个存储时间戳的字段。
class MyModel(models.Model):
timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
然后以此按最新的时间戳来检索元素。
my_model.objects.order_by('-timestamp')[:3]
创建一个数据时间模型
created = models.DateTimeField(auto_now_add=True, null=True)
在视图中获取创建的字段
course = Course.objects.all().order_by('-created')[:6]
减去表示数据库中的最新数据,借助切片,我们得到最新的6个项目。