Opened 21 months ago
Closed 21 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
orderingby nonexistent fields.You added
is_successannotation 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.