#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/[email protected]/3.11.7/Frameworks/Python.framework/Versions/3.11/lib/python311.zip',
 
'/opt/homebrew/Cellar/[email protected]/3.11.7/Frameworks/Python.framework/Versions/3.11/lib/python3.11',
 
'/opt/homebrew/Cellar/[email protected]/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.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018db8f762f8-96842957-3ed5-40d3-917a-6ff3e25bbfa9-000000%40eu-central-1.amazonses.com.

Reply via email to