#35227: admin.display(ordering="") is raises exception while trying to ordering
field.
-----------------------------------------+------------------------
Reporter: yetem | Owner: nobody
Type: Bug | Status: new
Component: contrib.admin | Version: 5.0
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
I have two models.
{{{
class A(models.Model):
pass
class B(models.Model):
is_success = models.BooleanField(null=True)
a = models.ForeignKey(A, on_delete=models.CASCADE)
}}}
And have defined admin for `A` class, with field `is_success` from `B`
class, in that way:
{{{
class AAdmin(admin.ModelAdmin):
list_display = ("is_success", )
@admin.display(boolean=True, ordering="is_success")
def is_success(self, obj):
newest_b = obj.b_set.first()
if newest_b:
return newest_b.is_success
else:
return
}}}
When I tried to order by column `is_success`, Django admin raises an
exception:
{{{
FieldError at /admin/test_bug_ordering/a/
Cannot resolve keyword 'is_success' into field. Choices are: b, id
Request Method: GET
Request URL:
http://localhost:8000/admin/test_bug_ordering/a/?o=1
Django Version: 5.0.2
Exception Type: FieldError
Exception Value:
Cannot resolve keyword 'is_success' into field. Choices are: b, id
Exception Location:
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-
packages/django/db/models/sql/query.py, line 1772, in names_to_path
Raised during: django.contrib.admin.options.changelist_view
Python Executable:
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/bin/python
Python Version: 3.11.7
Python Path:
['/Users/mdabrowski/workspace/test_bug_ordering',
'/opt/homebrew/Cellar/pyt...@3.11/3.11.7/Frameworks/Python.framework/Versions/3.11/lib/python311.zip',
'/opt/homebrew/Cellar/pyt...@3.11/3.11.7/Frameworks/Python.framework/Versions/3.11/lib/python3.11',
'/opt/homebrew/Cellar/pyt...@3.11/3.11.7/Frameworks/Python.framework/Versions/3.11/lib/python3.11
/lib-dynload',
'/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-packages',
'/Users/mdabrowski/workspace/aion']
Server time: Sat, 17 Feb 2024 21:20:27 +0000
Traceback Switch to copy-and-paste view
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-
packages/django/core/handlers/exception.py, line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-packages/django/core/handlers/base.py,
line 197, in _get_response
response = wrapped_callback(request, *callback_args,
**callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-
packages/django/contrib/admin/options.py, line 715, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-packages/django/utils/decorators.py,
line 188, in _view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-packages/django/utils/decorators.py,
line 186, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-
packages/django/views/decorators/cache.py, line 80, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-
packages/django/contrib/admin/sites.py, line 240, in inner
return view(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-packages/django/utils/decorators.py,
line 48, in _wrapper
return bound_method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-packages/django/utils/decorators.py,
line 188, in _view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-packages/django/utils/decorators.py,
line 186, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-
packages/django/contrib/admin/options.py, line 1984, in changelist_view
cl = self.get_changelist_instance(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-
packages/django/contrib/admin/options.py, line 863, in
get_changelist_instance
return ChangeList(
…
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-
packages/django/contrib/admin/views/main.py, line 144, in __init__
self.queryset = self.get_queryset(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-
packages/django/contrib/admin/views/main.py, line 574, in get_queryset
qs = qs.order_by(*ordering)
^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-packages/django/db/models/query.py,
line 1701, in order_by
obj.query.add_ordering(*field_names)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-
packages/django/db/models/sql/query.py, line 2253, in add_ordering
self.names_to_path(item.split(LOOKUP_SEP),
self.model._meta)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
Local vars
/Users/mdabrowski/Library/Caches/pypoetry/virtualenvs/aion-
ATQLib67-py3.11/lib/python3.11/site-
packages/django/db/models/sql/query.py, line 1772, in names_to_path
raise FieldError(
^ …
Local vars
}}}
However, I discovered a strange behavior. I can add a SimpleFilter like
this:
{{{
class IsSuccessFilter(admin.SimpleListFilter):
title = "Is Success Filter"
parameter_name = "is_success"
def lookups(self, request, model_admin):
return [
("true", _("Yes")),
("false", _("No")),
("none", _("None")),
]
def queryset(self, request, queryset):
subquery = (
B.objects.filter(a_id=OuterRef("id"))
.values("is_success")[:1]
)
queryset = queryset.annotate(is_success=Subquery(subquery))
if self.value() == "true":
return queryset.filter(is_success=True)
elif self.value() == "false":
return queryset.filter(is_success=False)
elif self.value() == "none":
return queryset.exclude(is_success__isnull=True)
else:
return queryset
class AAdmin(admin.ModelAdmin):
list_display = ("is_success", )
list_filter = (IsSuccessFilter, )
@admin.display(boolean=True, ordering="is_success")
def is_success(self, obj):
newest_b = obj.b_set.first()
if newest_b:
return newest_b.is_success
else:
return
}}}
And now I can order by `is_success` until I turn on `facets` option. When
I click `Show counts` the exception occurs again, but without `Show
counts` ordering works correctly.
--
Ticket URL: <
https://code.djangoproject.com/ticket/35227>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.