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

时间:2022-07-15 22:49:45

I have a model:

我有一个模型:

class MyModel(models.Model):
   creation_date = models.DateTimeField(auto_now_add = True, editable=False)

   class Meta:
      get_latest_by = 'creation_date'

I had a query in my view that did the following:

在我的视图中有一个查询,它是这样的:

instances = MyModel.objects.all().order_by('creation_date')

And then later I wanted instances.latest(), but it would not give me the correct instance, in fact it gave me the first instance. Only when I set order_by to -creation_date or actually removed the order_by from the query did .latest() give me the correct instance. This also happens when I test this manually using python manage.py shell instead of in the view.

然后,我想要instance. latest(),但是它不能给我正确的实例,事实上它给了我第一个实例。只有当我将order_by设置为-creation_date或从查询中实际删除order_by时,才会给出正确的实例。当我使用python管理手动测试时也会发生这种情况。而不是在视图中。

So what I've done now is in the Model's Meta I've listed order_by = ['creation_date'] and not used that in the query, and that works.

所以我现在所做的是在我列出了order_by = ['creation_date']的模型的元数据中,而没有在查询中使用它,这是有效的。

I would have expected .latest() to always return the most recent instance based on a (date)(time) field. Could anyone tell me whether it's correct that .latest() behaves strangely when you use order_by in the query?

我希望.latest()总是基于(date)(time)字段返回最近的实例。谁能告诉我,在查询中使用order_by时,.latest()的异常行为是否正确?

3 个解决方案

#1


66  

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

我希望。最新的()总是以一个(日期)(时间)字段返回最近的实例。

The documentation says that

文档表示,

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.

如果模型的元数据指定get_latest_by,则可以将field_name参数保留为latest()。Django默认使用get_latest_中指定的字段。

All this means is that when you fire MyModel.objects.latest() you will get the latest instance based on the date/time field. And when I tested your code using sample data, it indeed did.

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

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

然后我想要instances.latest(),但它不会给我正确的实例,实际上它给了我第一个实例。

You have misunderstood the way latest() works. When called on MyModel.objects it returns the latest instance in the table. When called on a queryset, latest will return the first object in the queryset. Your queryset consisted of all instances of MyModel ordered by creation_date in ascending order. It is only natural then that latest on this queryset should return the first row of the queryset. This incidentally happens to be the oldest row in the table.

您误解了最新()的工作方式。当呼吁MyModel。对象,它返回表中的最新实例。当在queryset上调用时,latest将返回queryset中的第一个对象。您的queryset由按照升序顺序由creation_date排序的MyModel的所有实例组成。因此,这个queryset上的最新内容应该返回queryset的第一行,这是很自然的。这碰巧是表中最古老的一行。

One way to get a better understanding is to view the query fired for latest.

获得更好理解的一种方法是查看最近触发的查询。

Case 1:

案例1:

from django.db import connection
MyModel.objects.latest()
print connection.queries[-1]['sql']

This prints:

这个打印:

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

Note the ordering by creation_date DESC and the LIMIT clause. The former is thanks to get_latest_by whereas the latter is the contribution of latest.

注意creation_date DESC的排序和LIMIT子句。前者是get_latest_by的功劳,而后者是最新的贡献。

Now, case 2:

现在,情况2:

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

prints

打印

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

Note that the ordering has changed to creation_date ASC. This is the result of the explicit order_by. The LIMIT is tacked on er, later courtesy latest.

注意,排序已经更改为creation_date ASC。这是显式order_by的结果。这个限制是附加在er上的,后面是最新的礼貌。

Let us also see Case 3: where you explicitly specify the field_name for objects.latest().

让我们还看一下情形3:您在其中显式地指定对象.latest()的field_name。

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

shows

显示

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

#2


7  

I guess this is a known bug in Django that was fixed after 1.3 was released.

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

#3


0  

This worked for me

这为我工作

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

#1


66  

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

我希望。最新的()总是以一个(日期)(时间)字段返回最近的实例。

The documentation says that

文档表示,

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.

如果模型的元数据指定get_latest_by,则可以将field_name参数保留为latest()。Django默认使用get_latest_中指定的字段。

All this means is that when you fire MyModel.objects.latest() you will get the latest instance based on the date/time field. And when I tested your code using sample data, it indeed did.

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

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

然后我想要instances.latest(),但它不会给我正确的实例,实际上它给了我第一个实例。

You have misunderstood the way latest() works. When called on MyModel.objects it returns the latest instance in the table. When called on a queryset, latest will return the first object in the queryset. Your queryset consisted of all instances of MyModel ordered by creation_date in ascending order. It is only natural then that latest on this queryset should return the first row of the queryset. This incidentally happens to be the oldest row in the table.

您误解了最新()的工作方式。当呼吁MyModel。对象,它返回表中的最新实例。当在queryset上调用时,latest将返回queryset中的第一个对象。您的queryset由按照升序顺序由creation_date排序的MyModel的所有实例组成。因此,这个queryset上的最新内容应该返回queryset的第一行,这是很自然的。这碰巧是表中最古老的一行。

One way to get a better understanding is to view the query fired for latest.

获得更好理解的一种方法是查看最近触发的查询。

Case 1:

案例1:

from django.db import connection
MyModel.objects.latest()
print connection.queries[-1]['sql']

This prints:

这个打印:

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

Note the ordering by creation_date DESC and the LIMIT clause. The former is thanks to get_latest_by whereas the latter is the contribution of latest.

注意creation_date DESC的排序和LIMIT子句。前者是get_latest_by的功劳,而后者是最新的贡献。

Now, case 2:

现在,情况2:

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

prints

打印

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

Note that the ordering has changed to creation_date ASC. This is the result of the explicit order_by. The LIMIT is tacked on er, later courtesy latest.

注意,排序已经更改为creation_date ASC。这是显式order_by的结果。这个限制是附加在er上的,后面是最新的礼貌。

Let us also see Case 3: where you explicitly specify the field_name for objects.latest().

让我们还看一下情形3:您在其中显式地指定对象.latest()的field_name。

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

shows

显示

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

#2


7  

I guess this is a known bug in Django that was fixed after 1.3 was released.

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

#3


0  

This worked for me

这为我工作

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