Opened 9 months ago
Closed 9 months ago
#35227 closed Bug (invalid)
admin.display(ordering="") is raises exception while trying to ordering field.
Reported by: | yetem | Owned by: | nobody |
---|---|---|---|
Component: | contrib.admin | Version: | 5.0 |
Severity: | Normal | Keywords: | |
Cc: | yetem | 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 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/python@3.11/3.11.7/Frameworks/Python.framework/Versions/3.11/lib/python311.zip', '/opt/homebrew/Cellar/python@3.11/3.11.7/Frameworks/Python.framework/Versions/3.11/lib/python3.11', '/opt/homebrew/Cellar/python@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.
Note:
See TracTickets
for help on using tickets.
This is an expected behavior, you cannot set
ordering
by nonexistent fields.You added
is_success
annotation to the queryset so now you can order by it.This is probably a duplicate of #35198.
Marking as "invalid" as it seems that you're experimenting with Django admin. If you're having trouble understanding how Django works, see TicketClosingReasons/UseSupportChannels for ways to get help.