mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Refs #29428 -- Fixed admin check crash when using a query expression in ModelAdmin.ordering.
This commit is contained in:
		| @@ -10,6 +10,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, | ||||
| ) | ||||
| @@ -489,7 +490,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( | ||||
|   | ||||
| @@ -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`). | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
| @@ -829,6 +831,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): | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user