[1.11.x] Fixed #28262 -- Fixed incorrect DisallowedModelAdminLookup when a nested reverse relation is in list_filter.
Backport of b7f99f84bc
from master
This commit is contained in:
parent
b7d6077517
commit
834d57b4de
|
@ -360,7 +360,7 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)):
|
||||||
# It is allowed to filter on values that would be found from local
|
# It is allowed to filter on values that would be found from local
|
||||||
# model anyways. For example, if you filter on employee__department__id,
|
# model anyways. For example, if you filter on employee__department__id,
|
||||||
# then the id value would be found already from employee__department_id.
|
# then the id value would be found already from employee__department_id.
|
||||||
if not prev_field or (prev_field.concrete and
|
if not prev_field or (prev_field.is_relation and
|
||||||
field not in prev_field.get_path_info()[-1].target_fields):
|
field not in prev_field.get_path_info()[-1].target_fields):
|
||||||
relation_parts.append(part)
|
relation_parts.append(part)
|
||||||
if not getattr(field, 'get_path_info', None):
|
if not getattr(field, 'get_path_info', None):
|
||||||
|
|
|
@ -15,3 +15,6 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed a regression causing ``Model.__init__()`` to crash if a field has an
|
* Fixed a regression causing ``Model.__init__()`` to crash if a field has an
|
||||||
instance only descriptor (:ticket:`28269`).
|
instance only descriptor (:ticket:`28269`).
|
||||||
|
|
||||||
|
* Fixed an incorrect ``DisallowedModelAdminLookup`` exception when using
|
||||||
|
a nested reverse relation in ``list_filter`` (:ticket:`28262`).
|
||||||
|
|
|
@ -82,12 +82,15 @@ class ChapterInline(admin.TabularInline):
|
||||||
|
|
||||||
|
|
||||||
class ChapterXtra1Admin(admin.ModelAdmin):
|
class ChapterXtra1Admin(admin.ModelAdmin):
|
||||||
list_filter = ('chap',
|
list_filter = (
|
||||||
'chap__title',
|
'chap',
|
||||||
'chap__book',
|
'chap__title',
|
||||||
'chap__book__name',
|
'chap__book',
|
||||||
'chap__book__promo',
|
'chap__book__name',
|
||||||
'chap__book__promo__name',)
|
'chap__book__promo',
|
||||||
|
'chap__book__promo__name',
|
||||||
|
'guest_author__promo__book',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ArticleAdmin(admin.ModelAdmin):
|
class ArticleAdmin(admin.ModelAdmin):
|
||||||
|
|
|
@ -77,6 +77,7 @@ class Book(models.Model):
|
||||||
class Promo(models.Model):
|
class Promo(models.Model):
|
||||||
name = models.CharField(max_length=100, verbose_name='¿Name?')
|
name = models.CharField(max_length=100, verbose_name='¿Name?')
|
||||||
book = models.ForeignKey(Book, models.CASCADE)
|
book = models.ForeignKey(Book, models.CASCADE)
|
||||||
|
author = models.ForeignKey(User, models.SET_NULL, blank=True, null=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
@ -100,6 +101,7 @@ class Chapter(models.Model):
|
||||||
class ChapterXtra1(models.Model):
|
class ChapterXtra1(models.Model):
|
||||||
chap = models.OneToOneField(Chapter, models.CASCADE, verbose_name='¿Chap?')
|
chap = models.OneToOneField(Chapter, models.CASCADE, verbose_name='¿Chap?')
|
||||||
xtra = models.CharField(max_length=100, verbose_name='¿Xtra?')
|
xtra = models.CharField(max_length=100, verbose_name='¿Xtra?')
|
||||||
|
guest_author = models.ForeignKey(User, models.SET_NULL, blank=True, null=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '¿Xtra1: %s' % self.xtra
|
return '¿Xtra1: %s' % self.xtra
|
||||||
|
|
|
@ -612,6 +612,11 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
|
||||||
'values': [p.name for p in Promo.objects.all()],
|
'values': [p.name for p in Promo.objects.all()],
|
||||||
'test': lambda obj, value: obj.chap.book.promo_set.filter(name=value).exists(),
|
'test': lambda obj, value: obj.chap.book.promo_set.filter(name=value).exists(),
|
||||||
},
|
},
|
||||||
|
# A forward relation (book) after a reverse relation (promo).
|
||||||
|
'guest_author__promo__book__id__exact': {
|
||||||
|
'values': [p.id for p in Book.objects.all()],
|
||||||
|
'test': lambda obj, value: obj.guest_author.promo_set.filter(book=value).exists(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for filter_path, params in filters.items():
|
for filter_path, params in filters.items():
|
||||||
for value in params['values']:
|
for value in params['values']:
|
||||||
|
|
Loading…
Reference in New Issue