From 0d8e3e608ee9aab5076d497664aa97e0a29e523e Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 14 Jun 2018 14:22:04 -0400 Subject: [PATCH] Fixed #29428 -- Fixed admin changelist crash when using a query expression without asc()/desc() in the ordering. --- django/contrib/admin/views/main.py | 6 ++++-- docs/releases/2.0.7.txt | 3 ++- tests/admin_changelist/tests.py | 11 +++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index cbbe45a5c7..3febd42fb9 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -17,7 +17,7 @@ from django.core.exceptions import ( ) from django.core.paginator import InvalidPage from django.db import models -from django.db.models.expressions import F, OrderBy +from django.db.models.expressions import Combinable, F, OrderBy from django.urls import reverse from django.utils.http import urlencode from django.utils.timezone import make_aware @@ -326,7 +326,9 @@ class ChangeList: # the right column numbers absolutely, because there might be more # than one column associated with that ordering, so we guess. for field in ordering: - if isinstance(field, OrderBy): + if isinstance(field, (Combinable, OrderBy)): + if not isinstance(field, OrderBy): + field = field.asc() if isinstance(field.expression, F): order_type = 'desc' if field.descending else 'asc' field = field.expression.name diff --git a/docs/releases/2.0.7.txt b/docs/releases/2.0.7.txt index 40c46d76a6..46d6e86073 100644 --- a/docs/releases/2.0.7.txt +++ b/docs/releases/2.0.7.txt @@ -9,4 +9,5 @@ Django 2.0.7 fixes several bugs in 2.0.6. Bugfixes ======== -* ... +* Fixed admin changelist crash when using a query expression without ``asc()`` + or ``desc()`` in the page's ordering (:ticket:`29428`). diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index 9f9150f34d..6c9b424a5a 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -77,6 +77,17 @@ class ChangeListTests(TestCase): cl = m.get_changelist_instance(request) self.assertEqual(cl.get_ordering_field_columns(), {3: 'desc', 2: 'asc'}) + def test_specified_ordering_by_f_expression_without_asc_desc(self): + class OrderedByFBandAdmin(admin.ModelAdmin): + list_display = ['name', 'genres', 'nr_of_members'] + ordering = (F('nr_of_members'), Upper('name'), F('genres')) + + m = OrderedByFBandAdmin(Band, custom_site) + request = self.factory.get('/band/') + request.user = self.superuser + cl = m.get_changelist_instance(request) + self.assertEqual(cl.get_ordering_field_columns(), {3: 'asc', 2: 'asc'}) + def test_select_related_preserved(self): """ Regression test for #10348: ChangeList.get_queryset() shouldn't