Fixed #27356 -- Fixed ModelAdmin.lookup_allowed() for some nested relations.
This commit is contained in:
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.
|
||||
|
|
Loading…
Reference in New Issue