#34615 closed Bug (wontfix)
queryset.order_by().first() is not consistent with other queryset behaviours
Reported by: | Iuri de Silvio | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 4.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
For any other operation, an empty .order_by()
remove default ordering, but it orders by pk
when .first()
is called.
>>> User.objects.only("pk").order_by()[:1] SELECT "auth_user"."id" FROM "auth_user" LIMIT 1
>>> User.objects.only("pk").order_by().first() SELECT "auth_user"."id" FROM "auth_user" ORDER BY "auth_user"."id" ASC LIMIT 1
I think it is an "undefined behavior" and it should build the query without ordering.
The ~almost~ undocumented implementation for this today should be:
try: user = User.objects.only("pk")[0] except IndexError: user = None
Change History (7)
comment:1 by , 2 years ago
Component: | Uncategorized → Database layer (models, ORM) |
---|---|
Type: | Uncategorized → Bug |
comment:2 by , 2 years ago
Has patch: | set |
---|
comment:3 by , 2 years ago
Patch needs improvement: | set |
---|
comment:4 by , 2 years ago
Resolution: | → wontfix |
---|---|
Status: | assigned → closed |
comment:5 by , 2 years ago
Thanks! I disagree a bit because if I'm explicitly disabling ordering with an empty order_by
, it is not the same as not defining ordering.
I'll follow up on mailing list.
comment:7 by , 2 years ago
Thanks! I disagree a bit because if I'm explicitly disabling ordering with an empty order_by, it is not the same as not defining ordering.
I get your original point, but I agree with Mariusz and the original authors adding this behaviour.
To have a first/last you must have deterministic ordering and not whatever the database feels like it wants to do otherwise this will start to introduce subtle soul-destroying bugs. I've numerous tests fail intermittently (with the same db) because we forgot to add explicit ordering.
We added
order_by("pk")
only when it's not explicitly ordered, mainly, to get the consistent and stable behavior on all backends. It's been that way basically forever and, IMO, we shouldn't change it. You can start a discussion on DevelopersMailingList if you don't agree.