#35665 closed Bug (fixed)
Prefetch() fails with "OrderByList" when queryset has no order_by and is sliced
Reported by: | Andrew | Owned by: | Simon Charette |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 5.1 |
Severity: | Release blocker | Keywords: | prefetch slice order_by |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
In v5.1
the Prefetch operator causes an issue when no order_by()
is specified, and the query contains a slice.
- Must have no order by (either explict
order_by()
or model Meta contains no order by) - Must be sliced - any form works,
:10
,10:
,10:20
Does not crash in v5.0.7
. I did not see this mentioned in the Prefetch
documentation, or the changelog.
short_list = Prefetch( "products", queryset=Product.objects.order_by()[:10], to_attr="short_list", ) query = Store.objects.prefetch_related(short_list) print(query) # errors
The stack trace:
File "python3.12/site-packages/django/db/models/expressions.py", line 1896, in __init__ self.order_by = OrderByList(*self.order_by) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "python3.12/site-packages/django/db/models/expressions.py", line 1414, in __init__ super().__init__(*expressions, **extra) File "python3.12/site-packages/django/db/models/expressions.py", line 1382, in __init__ raise ValueError( ValueError: OrderByList requires at least one expression.
I was able to replicate this in a clean project, against sqlite, with the following 2 simple models, used in the example above:
class Store(models.Model): name = models.CharField(max_length=100) class Product(models.Model): store = models.ForeignKey(Store, on_delete=models.CASCADE, related_name='products') name = models.CharField(max_length=100) class Meta: ordering = ['name']
Change History (6)
comment:1 by , 4 months ago
Keywords: | order_by added |
---|---|
Owner: | set to |
Severity: | Normal → Release blocker |
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
follow-up: 3 comment:2 by , 4 months ago
Has patch: | set |
---|
comment:3 by , 3 months ago
Replying to Simon Charette:
Yes, it returns them in database order, which is acceptable in this case.
This actually came up due to a Model having no Meta.ordering
, which is our standard. All ordering must be explicit at the query level.
comment:4 by , 3 months ago
Triage Stage: | Accepted → Ready for checkin |
---|
I managed to reproduce and the issue the issue is relatively simple to address.
It should obviously not crash but just so you know using slicing without ordering generally makes little sense as the backend is allowed to return rows in any order.