Opened 9 years ago
Last modified 20 months ago
#27752 new Bug
Fix and test admin_order_field set for the __str__ of a model
| Reported by: | Claude Paroz | Owned by: | |
|---|---|---|---|
| Component: | contrib.admin | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | renato+github@…, Ülgen Sarıkavak | Triage Stage: | Accepted |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
While doing some force_str cleanup on Django 2.0, Tim Graham and me noticed a possible issue with admin_order_field on a __str__method (in django.contrib.admin.utils.label_for_field). It's apparently untested. See this related commit [1], with a test that was later removed [2].
https://github.com/django/django/commit/2304ca423640a7b06390530bf61c879f9ff9e4ba
https://github.com/django/django/commit/65cc646c4801e3f3e1df1ab06dfaa763fa4b7b22
So a test for the proper label and sorting is wanted. See test_change_list_sorting_model_admin in tests/admin_views/tests.py for a similar test.
Change History (10)
comment:1 by , 9 years ago
| Cc: | added |
|---|---|
| Owner: | changed from to |
| Status: | new → assigned |
comment:2 by , 9 years ago
| Cc: | removed |
|---|---|
| Owner: | removed |
| Status: | assigned → new |
comment:3 by , 9 years ago
| Cc: | added |
|---|
comment:4 by , 9 years ago
comment:5 by , 9 years ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
comment:6 by , 9 years ago
Hey, I think I found the issue here.
Changing as you said attr = str to attr = model.__str__ it makes the column clickable and adds the field position to the o querystring. The problem is that when it gets to the admin view (here: https://github.com/django/django/blob/master/django/contrib/admin/views/main.py#L227-L233) it verifies first if the attribute is an instance of the model_admin class and it turns out that ModelAdmin has a str field, not carrying the model.__str__.admin_order_field attribute to the ordering query.
this is the attr representation with the model_admin elif <bound method ModelAdmin.__str__ of <core.admin.QuestionAdmin object at 0x7f82d7bc7748>
for testing purposes I removed the model_admin and got this
<function Question.__str__ at 0x7f04c9ea5598> and it had the admin_order_field attribute, making ordering work properly.
I still don't know how to solve this and would be awesome to have your help on this.
Thanks
comment:7 by , 9 years ago
Is it worth adding a special case in get_ordering_field() to get __str__() from the model instead of the ModelAdmin (which probably wouldn't have a useful __str__()? I think probably not. We might just document that admin_order_field isn't usable with Model.__str__() and move on to more important issues.
comment:8 by , 9 years ago
I'm trying to write something here but nothing seems to fit. Maybe because I'm not fluent on English
* The ``__str__()`` method is just as valid in ``list_display`` as any
other model method, so it's perfectly OK to do this::
list_display = ('__str__', 'some_other_field')
* Usually, elements of ``list_display`` that aren't actual database
fields can't be used in sorting (because Django does all the sorting
at the database level).
However, if an element of ``list_display`` represents a certain
database field, you can indicate this fact by setting the
``admin_order_field`` attribute of the item.
This rule doesn't apply to ``__str__`` method.
It's missing why it's not applicable, but It's not clear to me how to say that
comment:9 by , 4 years ago
| Owner: | removed |
|---|---|
| Status: | assigned → new |
comment:10 by , 20 months ago
| Cc: | added |
|---|
For example, adding to the
Questionmodel in the tutorial:__str__.admin_order_field = 'question_text'and to
QuestionAdmin:list_display = ('__str__', ...)should reproduce this. You'll see that the
__str__column isn't clickable for sorting like it should be. In thelable_for_fieldfunction, I tried changingattr = strtoattr = model.__str__-- this makes the column clickable but sorting still doesn't seem to work correctly.