summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2017-12-27 18:38:30 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2017-12-27 18:46:05 +0100
commitb54302d2269e54cfc2a9594b1f3e652e1fd089ed (patch)
tree834ac5b029640c3daee54af49a64b889fd3f706f
parent1b27374b0de49dd6afff80b730774bccc9551cc3 (diff)
[2.0.x] Fixed #28958 -- Fixed admin changelist crash when using a query expression in the page's ordering.
Thanks Tim Graham for the review. Backport of c8152137400b5932578cd1788b79560c9772e56b from master
-rw-r--r--django/contrib/admin/views/main.py9
-rw-r--r--docs/releases/2.0.1.txt3
-rw-r--r--tests/admin_changelist/tests.py16
3 files changed, 27 insertions, 1 deletions
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
index 541d1aacc4..495ab8e4a0 100644
--- a/django/contrib/admin/views/main.py
+++ b/django/contrib/admin/views/main.py
@@ -15,6 +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.urls import reverse
from django.utils.http import urlencode
from django.utils.translation import gettext
@@ -288,7 +289,13 @@ 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 field.startswith('-'):
+ if isinstance(field, OrderBy):
+ if isinstance(field.expression, F):
+ order_type = 'desc' if field.descending else 'asc'
+ field = field.expression.name
+ else:
+ continue
+ elif field.startswith('-'):
field = field[1:]
order_type = 'desc'
else:
diff --git a/docs/releases/2.0.1.txt b/docs/releases/2.0.1.txt
index 97260ef5b8..0c3a571913 100644
--- a/docs/releases/2.0.1.txt
+++ b/docs/releases/2.0.1.txt
@@ -40,3 +40,6 @@ Bugfixes
* Fixed a crash when chaining ``values()`` or ``values_list()`` after
``QuerySet.select_for_update(of=(...))`` (:ticket:`28944`).
+
+* Fixed admin changelist crash when using a query expression in the page's
+ ordering (:ticket:`28958`).
diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py
index b4c08b3e84..e884a8671d 100644
--- a/tests/admin_changelist/tests.py
+++ b/tests/admin_changelist/tests.py
@@ -8,6 +8,8 @@ from django.contrib.admin.tests import AdminSeleniumTestCase
from django.contrib.admin.views.main import ALL_VAR, SEARCH_VAR
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
+from django.db.models import F
+from django.db.models.functions import Upper
from django.template import Context, Template
from django.test import TestCase, override_settings
from django.test.client import RequestFactory
@@ -55,6 +57,20 @@ class ChangeListTests(TestCase):
request.user = user
return request
+ def test_specified_ordering_by_f_expression(self):
+ class OrderedByFBandAdmin(admin.ModelAdmin):
+ list_display = ['name', 'genres', 'nr_of_members']
+ ordering = (
+ F('nr_of_members').desc(nulls_last=True),
+ Upper(F('name')).asc(),
+ F('genres').asc(),
+ )
+
+ m = OrderedByFBandAdmin(Band, custom_site)
+ request = self.factory.get('/band/')
+ cl = m.get_changelist_instance(request)
+ self.assertEqual(cl.get_ordering_field_columns(), {3: 'desc', 2: 'asc'})
+
def test_select_related_preserved(self):
"""
Regression test for #10348: ChangeList.get_queryset() shouldn't