#31975 closed New feature (wontfix)
Add support for list of fields to admin_order_field.
Reported by: | Petr Dlouhý | Owned by: | nobody |
---|---|---|---|
Component: | contrib.admin | Version: | 3.1 |
Severity: | Normal | Keywords: | admin_order_field, ModelAdmin |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If I try to assign list to admin_order_field
to sort on multiple fields (like Model.Meta.ordering
does) like this:
@admin.register(Invoice) class InvoiceAdmin(ModelAdmin): def get_full_number(self, invoice): return invoice.full_number get_full_number.admin_order_field = ['issued__year', 'issued__month', '-number']
I got following error:
File "/home/petr/.local/share/virtualenvs/blenderhub_server-eFlwzMqz/lib/python3.7/site-packages/django/contrib/admin/options.py", line 1693, in changelist_view cl = self.get_changelist_instance(request) File "/home/petr/.local/share/virtualenvs/blenderhub_server-eFlwzMqz/lib/python3.7/site-packages/django/contrib/admin/options.py", line 748, in get_changelist_instance sortable_by, File "/home/petr/.local/share/virtualenvs/blenderhub_server-eFlwzMqz/lib/python3.7/site-packages/django/contrib/admin/views/main.py", line 99, in __init__ self.queryset = self.get_queryset(request) File "/home/petr/.local/share/virtualenvs/blenderhub_server-eFlwzMqz/lib/python3.7/site-packages/django/contrib/admin/views/main.py", line 479, in get_queryset ordering = self.get_ordering(request, qs) File "/home/petr/.local/share/virtualenvs/blenderhub_server-eFlwzMqz/lib/python3.7/site-packages/django/contrib/admin/views/main.py", line 328, in get_ordering elif order_field.startswith('-') and pfx == '-': AttributeError: 'list' object has no attribute 'startswith'
This is similar to https://code.djangoproject.com/ticket/30981 which has been fixed, but sorting on multiple fields is still hard to achieve.
Change History (7)
comment:1 by , 4 years ago
Keywords: | admin_order_field ModelAdmin added |
---|
comment:2 by , 4 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:3 by , 4 years ago
@Mariusz Felisiak You cannot achieve the intended behaviour by that Concat
, because
a) I wanted to sort the number in reverse order
b) The length and content of the concatenated strings can vary.
I spend quite some time figuring up that concatenate function, until finally I gave up.
So I think, this is valid use case for feature request, because the concatenation is either not possible at all, or it would be quite complex and very unreadable code.
I looked at the ChangeList.get_ordering()
function, and since it returns ordering list it might be quite simple code.
comment:4 by , 4 years ago
Resolution: | invalid |
---|---|
Status: | closed → new |
I tried to modify the code of the get_ordering
function, and I came with following changed code (based on Django 3.0 code), that seems to be working as expected (it is just the section in the try
- catch
block):
none, pfx, idx = p.rpartition('-') field_name = self.list_display[int(idx)] ordering_fields = self.get_ordering_field(field_name) if not isinstance(ordering_fields, list): ordering_fields = [ordering_fields] for order_field in ordering_fields: if not order_field: continue # No 'admin_order_field', skip it if hasattr(order_field, 'as_sql'): # order_field is an expression. ordering.append(order_field.desc() if pfx == '-' else order_field.asc()) # reverse order if order_field has already "-" as prefix elif order_field.startswith('-') and pfx == '-': ordering.append(order_field[1:]) else: ordering.append(pfx + order_field)
comment:5 by , 4 years ago
Type: | Uncategorized → New feature |
---|
comment:6 by , 4 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Summary: | admin_order_field in ModelAdmin doesn't support sorting on multiple columns → Add support for list of fields to admin_order_field. |
I'm not convinced, it looks niche. We don't want to add unnecessary complexity to the API. If you have a property that generates full_number
you should be able to use database functions to do the same, e.g. use LPad()
to get the same length etc. On the other hand, if full_number
is really complex I would recommend to store it in the database instead of using a dynamic property.
You can start a discussion on DevelopersMailingList if you don't agree.
comment:7 by , 3 years ago
I don't think, that is that niche, I even found Django snippet for this created years ago: https://djangosnippets.org/snippets/10471/
On one hand it is small modification of Django code and small increase in API complexity (which is consistent with the logic of other order fields, BTW), on the other hand is many hours spend by programmers creating unreadable Concat code in users applications and/or copying of large portion of get_queryset
function.
admin_order_field
doesn't support multiple columns as documented, you can try to useadmin_order_field = Concat('issued__year', 'issued__month', 'number')
.