summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2018-06-14 14:47:20 -0400
committerTim Graham <timograham@gmail.com>2018-06-15 10:12:44 -0400
commit83986af95dc432e54ba71f0c5c13f5e5c02c92e5 (patch)
tree143140e5bf00270c70ce28a11f414429a5aff147
parent4bccfac36fa765494cbaa03f79453f97a92ec921 (diff)
[2.0.x] Refs #29428 -- Fixed admin check crash when using a query expression in ModelAdmin.ordering.
Backport of ec2c9c353113bb1db6e32ed3f0b6c28bc06ca2eb from master
-rw-r--r--django/contrib/admin/checks.py9
-rw-r--r--docs/releases/2.0.7.txt3
-rw-r--r--tests/modeladmin/test_checks.py19
3 files changed, 30 insertions, 1 deletions
diff --git a/django/contrib/admin/checks.py b/django/contrib/admin/checks.py
index 97d1a4134a..ff0e8651ed 100644
--- a/django/contrib/admin/checks.py
+++ b/django/contrib/admin/checks.py
@@ -9,6 +9,7 @@ from django.core import checks
from django.core.exceptions import FieldDoesNotExist
from django.db import models
from django.db.models.constants import LOOKUP_SEP
+from django.db.models.expressions import Combinable, F, OrderBy
from django.forms.models import (
BaseModelForm, BaseModelFormSet, _get_foreign_key,
)
@@ -485,7 +486,13 @@ class BaseModelAdminChecks:
def _check_ordering_item(self, obj, model, field_name, label):
""" Check that `ordering` refers to existing fields. """
-
+ if isinstance(field_name, (Combinable, OrderBy)):
+ if not isinstance(field_name, OrderBy):
+ field_name = field_name.asc()
+ if isinstance(field_name.expression, F):
+ field_name = field_name.expression.name
+ else:
+ return []
if field_name == '?' and len(obj.ordering) != 1:
return [
checks.Error(
diff --git a/docs/releases/2.0.7.txt b/docs/releases/2.0.7.txt
index 46d6e86073..4890ee2dba 100644
--- a/docs/releases/2.0.7.txt
+++ b/docs/releases/2.0.7.txt
@@ -11,3 +11,6 @@ Bugfixes
* Fixed admin changelist crash when using a query expression without ``asc()``
or ``desc()`` in the page's ordering (:ticket:`29428`).
+
+* Fixed admin check crash when using a query expression in
+ ``ModelAdmin.ordering`` (:ticket:`29428`).
diff --git a/tests/modeladmin/test_checks.py b/tests/modeladmin/test_checks.py
index 5559a8fe3c..b6a80a29a5 100644
--- a/tests/modeladmin/test_checks.py
+++ b/tests/modeladmin/test_checks.py
@@ -3,6 +3,8 @@ from django.contrib.admin import BooleanFieldListFilter, SimpleListFilter
from django.contrib.admin.options import VERTICAL, ModelAdmin, TabularInline
from django.contrib.admin.sites import AdminSite
from django.core.checks import Error
+from django.db.models import F
+from django.db.models.functions import Upper
from django.forms.models import BaseModelFormSet
from django.test import SimpleTestCase
@@ -815,6 +817,23 @@ class OrderingCheckTests(CheckTestCase):
self.assertIsValid(TestModelAdmin, ValidationTestModel)
+ def test_invalid_expression(self):
+ class TestModelAdmin(ModelAdmin):
+ ordering = (F('nonexistent'), )
+
+ self.assertIsInvalid(
+ TestModelAdmin, ValidationTestModel,
+ "The value of 'ordering[0]' refers to 'nonexistent', which is not "
+ "an attribute of 'modeladmin.ValidationTestModel'.",
+ 'admin.E033'
+ )
+
+ def test_valid_expression(self):
+ class TestModelAdmin(ModelAdmin):
+ ordering = (Upper('name'), Upper('band__name').desc())
+
+ self.assertIsValid(TestModelAdmin, ValidationTestModel)
+
class ListSelectRelatedCheckTests(CheckTestCase):