我有一个模特:
class MyModel(models.Model):
creation_date = models.DateTimeField(auto_now_add = True, editable=False)
class Meta:
get_latest_by = 'creation_date'
我的观点中有一个查询执行了以下操作:
instances = MyModel.objects.all().order_by('creation_date')
然后我想要instances.latest()
,但它不会给我正确的实例,事实上它给了我第一个实例。只有当我将order_by设置为-creation_date
或实际从查询中删除了order_by时,.latest()
才能为我提供正确的实例。当我使用python manage.py shell而不是在视图中手动测试时,也会发生这种情况。
所以我现在所做的就是在模型的Meta我列出的order_by = ['creation_date']
中,并没有在查询中使用它,这是有效的。
我希望.latest()
始终根据(日期)(时间)字段返回最新的实例。当你在查询中使用.latest()
时,有人能告诉我order_by
是否表现得很奇怪?
答案 0 :(得分:67)
我原以为.latest()总是根据(日期)(时间)字段返回最新的实例。
如果您的模型
Meta
指定get_latest_by
,您可以将field_name
参数留给latest()
。 Django默认使用get_latest_by
中指定的字段。
所有这些意味着当您解雇MyModel.objects.latest()
时,您将根据日期/时间字段获取最新实例。当我使用示例数据测试您的代码时,确实如此。
然后我想要instances.latest(),但它不会给我正确的实例,事实上它给了我第一个实例。
你误解了latest()
的工作方式。在 MyModel.objects 上调用时,它会返回
表中的最新实例。在 queryset 上调用时,latest
将返回查询集中的第一个对象。您的查询集由MyModel
按{1}}按升序排序的所有实例组成。很自然,此查询集上的creation_date
应该返回查询集的第一行行。这恰好是表中最旧的行。
获得更好理解的一种方法是查看为latest
触发的查询。
案例1:
latest
打印:
from django.db import connection
MyModel.objects.latest()
print connection.queries[-1]['sql']
请注意SELECT "app_mymodel"."id", "app_mymodel"."creation_date" FROM
"app_mymodel" ORDER BY "app_mymodel"."creation_date" DESC LIMIT 1
和creation_date DESC
子句的排序。前者是LIMIT
,而后者是get_latest_by
的贡献。
现在,案例2:
latest
打印
MyModel.objects.order_by('creation_date').latest()
print connection.queries[-1]['sql']
请注意,排序已更改为SELECT "app_mymodel"."id", "app_mymodel"."creation_date" FROM
"app_mymodel" ORDER BY "app_mymodel"."creation_date" ASC LIMIT 1
。这是显式creation_date ASC
的结果。 order_by
被贬低,后来礼貌LIMIT
。
让我们看一下案例3:您明确指定latest
的{{1}}。
field_name
显示
objects.latest()
答案 1 :(得分:7)
我想这是一个已知的bug in Django,在1.3发布后修复了。
答案 2 :(得分:0)
这对我有用
latestsetuplist = SetupTemplate.objects.order_by('-creationTime')[:10][::1]
答案 3 :(得分:0)
如果我们有 id 或 date 的值
post_id = BlogPost.objects.get(id=id)
try:
previous_post = BlogPost.objects.all().order_by('id')[post_id.id-2:post_id.id-1]
except:
previous_post = None
try:
next_post = BlogPost.objects.all().order_by('id')[post_id.id:post_id.id+1]
except:
next_post = None
它对我有用,即使缺少 id 它也会选择下一个或上一个值