Python 使用 .order_by() 和 .latest() 的 Django 查询
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3736964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django Query using .order_by() and .latest()
提问by Heyl1
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_dateor 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.
后来我想要instances.latest(),但它不会给我正确的实例,实际上它给了我第一个实例。只有当我将 order_by 设置为-creation_date或实际从查询中删除 order_by 时,才.latest()给了我正确的实例。当我使用 python manage.py shell 而不是在视图中手动测试时,也会发生这种情况。
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_byin the query?
我本来希望.latest()总是根据(日期)(时间)字段返回最近的实例。谁能告诉我在查询中.latest()使用时行为异常是否正确order_by?
采纳答案by Manoj Govindan
I would have expected .latest() to always return the most recent instance based on a (date)(time) field.
我本来希望 .latest() 总是根据 (date)(time) 字段返回最近的实例。
The documentationsays that
该文件说,
If your model's
Metaspecifiesget_latest_by, you can leave off thefield_nameargument tolatest(). Django will use the field specified inget_latest_byby default.
如果您的模型
Meta指定了get_latest_by,则可以不使用field_name参数latest()。Django 将get_latest_by默认使用 中指定的字段。
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()您将获得基于日期/时间字段的最新实例。当我使用示例数据测试您的代码时,确实如此。
And then later I wanted instances.latest(), but it would not give me the correct instance, in fact it gave me the first instance.
后来我想要instance.latest(),但它不会给我正确的实例,实际上它给了我第一个实例。
You have misunderstood the way latest()works. When called on MyModel.objectsit returns
the latest instance in the table. When called on a queryset, latestwill return the first object in the queryset. Your queryset consisted of all instances of MyModelordered by creation_datein ascending order. It is only natural then that lateston this queryset should return the firstrow of the queryset. This incidentally happens to be the oldest row in the table.
你误解了工作方式latest()。当所谓的MyModel.objects它在返回的最新实例表。当一个叫做查询集,latest将在返回的第一个对象的查询集。您的查询集MyModel由creation_date按升序排列的所有实例组成。这是很自然那么latest这个查询集应该返回第一行的查询集的。这恰好是表中最旧的行。
One way to get a better understanding is to view the query fired for latest.
获得更好理解的一种方法是查看为 触发的查询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 DESCand the LIMITclause. The former is thanks to get_latest_bywhereas the latter is the contribution of latest.
注意order bycreation_date DESC和LIMIT子句。前者是感谢,get_latest_by后者是贡献latest。
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 LIMITis tacked on er, later courtesy latest.
请注意,排序已更改为creation_date ASC。这是显式的结果order_by。该LIMIT是上涨了急诊室,后来礼貌latest。
Let us also see Case 3: where you explicitly specify the field_namefor objects.latest().
让我们也看看案例 3:您明确指定field_namefor objects.latest()。
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
回答by Игорь Бронштейн
I guess this is a known bug in Djangothat was fixed after 1.3 was released.
回答by Manish Gupta
This worked for me
这对我有用
latestsetuplist = SetupTemplate.objects.order_by('-creationTime')[:10][::1]

