mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	Fixed #30543 -- Fixed checks of ModelAdmin.list_display for fields accessible only via instance.
Co-Authored-By: Andrew Simons <andrewsimons@bubblegroup.com>
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							7991111af1
						
					
				
				
					commit
					ed668796f6
				
			| @@ -720,12 +720,24 @@ class ModelAdminChecks(BaseModelAdminChecks): | ||||
|             return [] | ||||
|         elif hasattr(obj, item): | ||||
|             return [] | ||||
|         elif hasattr(obj.model, item): | ||||
|         try: | ||||
|             field = obj.model._meta.get_field(item) | ||||
|         except FieldDoesNotExist: | ||||
|                 return [] | ||||
|             else: | ||||
|             try: | ||||
|                 field = getattr(obj.model, item) | ||||
|             except AttributeError: | ||||
|                 return [ | ||||
|                     checks.Error( | ||||
|                         "The value of '%s' refers to '%s', which is not a " | ||||
|                         "callable, an attribute of '%s', or an attribute or " | ||||
|                         "method on '%s.%s'." % ( | ||||
|                             label, item, obj.__class__.__name__, | ||||
|                             obj.model._meta.app_label, obj.model._meta.object_name, | ||||
|                         ), | ||||
|                         obj=obj.__class__, | ||||
|                         id='admin.E108', | ||||
|                     ) | ||||
|                 ] | ||||
|         if isinstance(field, models.ManyToManyField): | ||||
|             return [ | ||||
|                 checks.Error( | ||||
| @@ -735,18 +747,6 @@ class ModelAdminChecks(BaseModelAdminChecks): | ||||
|                 ) | ||||
|             ] | ||||
|         return [] | ||||
|         else: | ||||
|             return [ | ||||
|                 checks.Error( | ||||
|                     "The value of '%s' refers to '%s', which is not a callable, " | ||||
|                     "an attribute of '%s', or an attribute or method on '%s.%s'." % ( | ||||
|                         label, item, obj.__class__.__name__, | ||||
|                         obj.model._meta.app_label, obj.model._meta.object_name, | ||||
|                     ), | ||||
|                     obj=obj.__class__, | ||||
|                     id='admin.E108', | ||||
|                 ) | ||||
|             ] | ||||
|  | ||||
|     def _check_list_display_links(self, obj): | ||||
|         """ Check that list_display_links is a unique subset of list_display. | ||||
|   | ||||
| @@ -3,7 +3,7 @@ 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 import F, Field, Model | ||||
| from django.db.models.functions import Upper | ||||
| from django.forms.models import BaseModelFormSet | ||||
| from django.test import SimpleTestCase | ||||
| @@ -509,6 +509,25 @@ class ListDisplayTests(CheckTestCase): | ||||
|  | ||||
|         self.assertIsValid(TestModelAdmin, ValidationTestModel) | ||||
|  | ||||
|     def test_valid_field_accessible_via_instance(self): | ||||
|         class PositionField(Field): | ||||
|             """Custom field accessible only via instance.""" | ||||
|             def contribute_to_class(self, cls, name): | ||||
|                 super().contribute_to_class(cls, name) | ||||
|                 setattr(cls, self.name, self) | ||||
|  | ||||
|             def __get__(self, instance, owner): | ||||
|                 if instance is None: | ||||
|                     raise AttributeError() | ||||
|  | ||||
|         class TestModel(Model): | ||||
|             field = PositionField() | ||||
|  | ||||
|         class TestModelAdmin(ModelAdmin): | ||||
|             list_display = ('field',) | ||||
|  | ||||
|         self.assertIsValid(TestModelAdmin, TestModel) | ||||
|  | ||||
|  | ||||
| class ListDisplayLinksCheckTests(CheckTestCase): | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user