Opened 2 years ago
Last modified 2 years ago
#34130 closed Bug
order_by() has no effect on values()/values_list() — at Initial Version
Reported by: | Michal Dabski | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.2 |
Severity: | Normal | Keywords: | queryset, ordering, values, values_list |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I have encounteded a bug with a model that has default ordering. I am making a query with order_by()
without parameters to avoid ordering and then use values()
or values_list()
to extract a subset of fields. The end result is an ordered queryset.
It appears that values()
restores model's default ordering if called after order_by()
, except if queryset is already ordered by cystom ordering (e.g. order_by('name')
), in which case order_by is maintained.
Django 3.2.16
The model:
class Dashboard(models.Model): name = models.CharField(max_length=100) order = models.PositiveIntegerField(default=1) class Meta: ordering = 'order',
Note: it is important that the model defineds ordering
To reproduce issue:
# Queryset is ordered by default field as expected ✔ str(Dashboard.objects.all().values('name').ordered) Out[44]: 'True' # Queryset is not ordered after adding order_by() as expected ✔ str(Dashboard.objects.all().order_by().ordered) Out[54]: 'False' # adding values() call somehow restores default ordering. Expected behaviour is for QS to remain unordered ✖ str(Dashboard.objects.all().order_by().values('name').ordered) Out[42]: 'True' # placing order_by() after values() works as expected ✔ str(Dashboard.objects.all().values('name').order_by().ordered) Out[48]: 'False'
In my case I am using order_by() to avoid using JOIN in the query when I know that order does not matter, but resulting query does make a join unbeknownst to me and makes the more complex ordered query.
The documentation for values/values_list and order_by does not appear to mention this behaviour so I am assuming it is not intentional.