mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #27356 -- Fixed ModelAdmin.lookup_allowed() for some nested relations.
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							27793431cf
						
					
				
				
					commit
					b27166b769
				
			| @@ -371,16 +371,20 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass): | ||||
|         if len(relation_parts) <= 1: | ||||
|             # Either a local field filter, or no fields at all. | ||||
|             return True | ||||
|         clean_lookup = LOOKUP_SEP.join(relation_parts) | ||||
|         valid_lookups = [self.date_hierarchy] | ||||
|         valid_lookups = {self.date_hierarchy} | ||||
|         for filter_item in self.list_filter: | ||||
|             if isinstance(filter_item, type) and issubclass(filter_item, SimpleListFilter): | ||||
|                 valid_lookups.append(filter_item.parameter_name) | ||||
|                 valid_lookups.add(filter_item.parameter_name) | ||||
|             elif isinstance(filter_item, (list, tuple)): | ||||
|                 valid_lookups.append(filter_item[0]) | ||||
|                 valid_lookups.add(filter_item[0]) | ||||
|             else: | ||||
|                 valid_lookups.append(filter_item) | ||||
|         return clean_lookup in valid_lookups | ||||
|                 valid_lookups.add(filter_item) | ||||
|  | ||||
|         # Is it a valid relational lookup? | ||||
|         return not { | ||||
|             LOOKUP_SEP.join(relation_parts), | ||||
|             LOOKUP_SEP.join(relation_parts + [part]) | ||||
|         }.isdisjoint(valid_lookups) | ||||
|  | ||||
|     def to_field_allowed(self, request, to_field): | ||||
|         """ | ||||
|   | ||||
| @@ -8,8 +8,10 @@ from django.contrib.admin.options import ( | ||||
| from django.contrib.admin.sites import AdminSite | ||||
| from django.contrib.admin.widgets import AdminDateWidget, AdminRadioSelect | ||||
| from django.contrib.auth.models import User | ||||
| from django.db import models | ||||
| from django.forms.widgets import Select | ||||
| from django.test import SimpleTestCase, TestCase | ||||
| from django.test.utils import isolate_apps | ||||
|  | ||||
| from .models import Band, Concert | ||||
|  | ||||
| @@ -90,6 +92,33 @@ class ModelAdminTests(TestCase): | ||||
|         ma = BandAdmin(Band, self.site) | ||||
|         self.assertTrue(ma.lookup_allowed('name__nonexistent', 'test_value')) | ||||
|  | ||||
|     @isolate_apps('modeladmin') | ||||
|     def test_lookup_allowed_onetoone(self): | ||||
|         class Department(models.Model): | ||||
|             code = models.CharField(max_length=4, unique=True) | ||||
|  | ||||
|         class Employee(models.Model): | ||||
|             department = models.ForeignKey(Department, models.CASCADE, to_field="code") | ||||
|  | ||||
|         class EmployeeProfile(models.Model): | ||||
|             employee = models.OneToOneField(Employee, models.CASCADE) | ||||
|  | ||||
|         class EmployeeInfo(models.Model): | ||||
|             employee = models.OneToOneField(Employee, models.CASCADE) | ||||
|             description = models.CharField(max_length=100) | ||||
|  | ||||
|         class EmployeeProfileAdmin(ModelAdmin): | ||||
|             list_filter = [ | ||||
|                 'employee__employeeinfo__description', | ||||
|                 'employee__department__code', | ||||
|             ] | ||||
|  | ||||
|         ma = EmployeeProfileAdmin(EmployeeProfile, self.site) | ||||
|         # Reverse OneToOneField | ||||
|         self.assertIs(ma.lookup_allowed('employee__employeeinfo__description', 'test_value'), True) | ||||
|         # OneToOneField and ForeignKey | ||||
|         self.assertIs(ma.lookup_allowed('employee__department__code', 'test_value'), True) | ||||
|  | ||||
|     def test_field_arguments(self): | ||||
|         # If fields is specified, fieldsets_add and fieldsets_change should | ||||
|         # just stick the fields into a formsets structure and return it. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user