[2.0.x] Fixed #29428 -- Fixed admin changelist crash when using a query expression without asc()/desc() in the ordering.

Backport of 0d8e3e608e from master
This commit is contained in:
Tim Graham 2018-06-14 14:22:04 -04:00
parent 9dfb6fcbd5
commit 4bccfac36f
3 changed files with 16 additions and 3 deletions

View File

@ -15,7 +15,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.translation import gettext
@ -289,7 +289,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

View File

@ -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`).

View File

@ -73,6 +73,16 @@ 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/')
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