获取查询集中的最后一条记录
Posted
技术标签:
【中文标题】获取查询集中的最后一条记录【英文标题】:Get last record in a queryset 【发布时间】:2011-01-12 13:22:39 【问题描述】:如何检索某个查询集中的最后一条记录?
【问题讨论】:
【参考方案1】:MyModel.objects.order_by('-id')[:1]
【讨论】:
【参考方案2】:在 Django 模板中,我必须这样做才能使其与反向查询集一起使用:
thread.forumpost_set.all.last
希望这对四处寻找该主题的人有所帮助。
【讨论】:
【参考方案3】:编辑:您现在必须使用Entry.objects.latest('pub_date')
你可以简单地做这样的事情,使用reverse()
:
queryset.reverse()[0]
另外,请注意来自 Django 文档的警告:
...注意
reverse()
应该 通常只在 QuerySet 上调用 它具有定义的顺序(例如, 当查询一个模型时 定义默认排序,或者当 使用order_by()
)。如果没有这样的订购 为给定的QuerySet
定义, 在它上面调用reverse()
没有真正的 效果(排序未定义 在致电reverse()
之前,将 之后保持未定义)。
【讨论】:
如 django 文档中所说:“请注意,reverse() 通常只应在具有已定义排序的 QuerySet 上调用(例如,在查询定义了默认排序的模型时,或者当使用 order_by())。如果没有为给定的 QuerySet 定义这样的排序,则对其调用 reverse() 没有实际效果(在调用 reverse() 之前排序未定义,之后将保持未定义)。" 2017 并且接受的答案现在已经过时了。如下所示,您应该使用 queryset.last()。【参考方案4】:您可以使用Model.objects.last()
或Model.objects.first()
。
如果没有定义ordering
,则查询集根据主键排序。如果你想要排序行为查询集,那么你可以参考最后两点。
如果您正在考虑这样做,Model.objects.all().last()
检索最后一个,Model.objects.all().first()
检索查询集中的第一个元素或使用filters
不加考虑。然后看看下面的一些注意事项。
这里要注意的重要部分是,如果您的模型中没有包含任何 ordering
,则数据可以按任何顺序排列,并且您将有一个意外的随机最后或第一个元素。
例如。假设您有一个名为 Model1
的模型,它有 2 列 id
和 item_count
,其中 10 行的 id 为 1 到 10。[没有定义排序]
如果你像这样获取 Model.objects.all().last(),你可以从 10 个元素的列表中获取任何元素。是的,它是随机的,因为没有默认排序。
那么有什么办法呢?
-
您可以根据模型上的任何一个或多个字段定义
ordering
。它也有性能问题,请也检查一下。参考:Here
或者您可以在获取时使用order_by
。
像这样:Model.objects.order_by('item_count').last()
【讨论】:
【参考方案5】:Django Doc:
latest(field_name=None)
使用作为日期字段提供的 field_name 按日期返回表中的最新对象。本例返回表中最新的Entry,根据
pub_date
字段:Entry.objects.latest('pub_date')
【讨论】:
这是一种简洁的方法。此外,根据文档,“如果您的模型的 Meta 指定 get_latest_by,您可以将 field_name 参数留给 latest()”。【参考方案6】:获取第一个对象:
ModelName.objects.first()
获取最后一个对象:
ModelName.objects.last()
你可以使用过滤器
ModelName.objects.filter(name='simple').first()
这对我有用。
【讨论】:
【参考方案7】:最简单的方法是:
books.objects.all().last()
您也可以使用它来获取第一个条目,如下所示:
books.objects.all().first()
【讨论】:
books.objects.last()
和 books.objects.first()
应该可以解决问题。
这应该是与XYZ.objects.first()
和XYZ.objects.last()
一起被接受的答案
我认为 Arnaud P 的方式更合适。如果没记错的话,这将解压缩 DB 中的所有项目,后者会使用 DB 查询提取最后一个项目。【参考方案8】:
当查询集已经用尽时,您可以这样做以避免另一个 db 提示 -
last = queryset[len(queryset) - 1] if queryset else None
不要使用try...except...
。
在这种情况下,Django 不会抛出 IndexError
。
它会抛出 AssertionError
或 ProgrammingError
(当您使用 -O 选项运行 python 时)
【讨论】:
假设您的查询集已经排序,这应该是“最佳答案”,因为它是唯一不会再次访问数据库的解决方案。【参考方案9】:Django >= 1.6
添加了 QuerySet 方法 first() 和 last(),它们是返回匹配过滤器的第一个或最后一个对象的便捷方法。如果没有匹配的对象,则返回 None。
【讨论】:
【参考方案10】:如果使用 django 1.6 及更高版本,现在引入新的 api 会容易得多 -
Model.object.earliest()
它会给出相反方向的 latest()。
附言- 我知道它的老问题,我发帖时好像有人会解决这个问题,他们会了解这个新功能,而不是最终使用旧方法。
【讨论】:
来自文档:earlyst() 和 latest() 需要模型中的 field_name 参数或“get_latest_by”【参考方案11】:无需担心当前排序的最简单方法是将 QuerySet 转换为列表,以便您可以使用 Python 的正常负索引。像这样:
list(User.objects.all())[-1]
【讨论】:
这将从数据库中查询所有对象,然后将获取第一个对象 好点!显然没有想到这一点。 .reverse() 答案(当前选择)是正确的方法!以上是关于获取查询集中的最后一条记录的主要内容,如果未能解决你的问题,请参考以下文章