Django中queryset的last()、latest()等方法的区别是什么?
Django中earliest()、latest()、first()、last()方法的区别
首先说你遇到的情况:latest() 没返回对象,是因为它必须依赖明确的排序字段——要么你的CustomUser模型在定义时设置了get_latest_by属性(指定默认排序字段,比如created_at),要么调用时必须传入字段参数,比如latest('created_at')。而last()是直接取当前查询集排序后的最后一条数据,如果你的查询集没指定排序,就会用模型默认的排序规则(比如主键id)。
下面详细拆解四个方法的核心区别:
1. first() 和 last()
- 这两个方法完全基于当前查询集的排序顺序返回数据:
first():返回查询集排序后的第一条记录last():返回查询集排序后的最后一条记录
- 如果查询集没有显式设置排序,会优先使用模型
ordering元组定义的默认排序;如果模型也没设置ordering,则按数据库默认存储顺序(通常是主键id升序)取值。 - 示例:
# 按id升序取第一条用户记录 CustomUser.objects.first() # 先按created_at降序排序,再取最后一条(即最早创建的用户) CustomUser.objects.order_by('-created_at').last()
2. earliest() 和 latest()
- 这两个方法是基于指定的日期/时间类字段,专门用来取最早/最晚的记录,本质等价于按该字段升序/降序后取第一条:
earliest(*fields):按传入字段升序排序,返回第一条(时间最早的记录)latest(*fields):按传入字段降序排序,返回第一条(时间最晚的记录)
- 如果模型定义了
get_latest_by属性(比如get_latest_by = 'updated_at'),调用时可以不传字段参数,默认使用该属性指定的字段;否则必须传入至少一个字段参数,否则会抛出TypeError。 - 示例:
# 必须传入字段参数,否则报错 CustomUser.objects.filter(email=email).latest('id') # 模型已设置get_latest_by='created_at',可直接调用 CustomUser.objects.earliest()
关键差异总结
| 方法 | 依赖规则 | 核心逻辑 |
|---|---|---|
first() | 查询集/模型的排序规则 | 取排序后的第一条记录 |
last() | 查询集/模型的排序规则 | 取排序后的最后一条记录 |
earliest() | 显式字段或模型的get_latest_by | 按指定字段升序取最早的记录 |
latest() | 显式字段或模型的get_latest_by | 按指定字段降序取最晚的记录 |
回到你的问题,解决方法很直接:要么给CustomUser模型添加get_latest_by = 'id'(或你用来记录插入时间的字段),要么调用latest()时传入字段参数,比如CustomUser.objects.filter(email=email).latest('id'),就能拿到你需要的最后插入的用户数据。
内容的提问来源于stack exchange,提问作者shraysalvi
相关产品推荐
相关产品推荐

