Django查询使用.order_by()和.latest()

2024-04-18 20:28:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个模型:

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()总是基于(日期)(时间)字段返回最近的实例。有人能告诉我当你在查询中使用order_by时,.latest()行为异常是否正确吗?


Tags: instances实例模型autodatebymodelmodels
3条回答

这对我有效

latestsetuplist = SetupTemplate.objects.order_by('-creationTime')[:10][::1]

I would have expected .latest() to always return the most recent instance based on a (date)(time) field.

documentation

If your model's Meta specifies get_latest_by, you can leave off the field_name argument to latest(). Django will use the field specified in get_latest_by by default.

这意味着,当您启动MyModel.objects.latest()时,您将根据日期/时间字段获得最新的实例。当我使用示例数据测试您的代码时,它确实做到了。

And then later I wanted instances.latest(), but it would not give me the correct instance, in fact it gave me the first instance.

你误解了latest()的工作方式。当调用MyModel.objects时,它返回 表中的最新实例。当对queryset调用时,latest将返回queryset中的第一个对象。您的queryset包含所有按creation_date升序排列的MyModel实例。只有这样,这个queryset上的latest才应该首先返回queryset。这碰巧是中最早的一行。

一种更好的理解方法是查看为latest激发的查询。

案例1:

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 DESCLIMIT子句排序。前者是由于get_latest_by,后者是latest的贡献。

现在,案例2:

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是附加在er上的,稍后由latest提供。

让我们也看看第3种情况:您显式地为objects.latest()指定field_name

MyModel.objects.latest('id')
print connection.queries[-1]['sql']

显示

SELECT "app_mymodel"."id", "app_mymodel"."creation_date" FROM "app_mymodel"
ORDER BY "app_mymodel"."id" DESC LIMIT 1

我想这是一个已知的bug in Django,在1.3发布后被修复。

相关问题 更多 >