Fixed #30231 -- Fixed admin filter horizontal/vertical verbose_name generation.

Co-authored-by: David Smith <smithdc@gmail.com>
This commit is contained in:
Teresa Partida 2021-02-11 10:27:33 +01:00 committed by Carlton Gibson
parent 06e5f7ae16
commit 45bef6706a
4 changed files with 119 additions and 11 deletions

View File

@ -218,12 +218,10 @@
// instantiate a new SelectFilter instance for it. // instantiate a new SelectFilter instance for it.
if (typeof SelectFilter !== 'undefined') { if (typeof SelectFilter !== 'undefined') {
$('.selectfilter').each(function(index, value) { $('.selectfilter').each(function(index, value) {
const namearr = value.name.split('-'); SelectFilter.init(value.id, this.dataset.fieldName, false);
SelectFilter.init(value.id, namearr[namearr.length - 1], false);
}); });
$('.selectfilterstacked').each(function(index, value) { $('.selectfilterstacked').each(function(index, value) {
const namearr = value.name.split('-'); SelectFilter.init(value.id, this.dataset.fieldName, true);
SelectFilter.init(value.id, namearr[namearr.length - 1], true);
}); });
} }
}; };
@ -283,12 +281,10 @@
// If any SelectFilter widgets were added, instantiate a new instance. // If any SelectFilter widgets were added, instantiate a new instance.
if (typeof SelectFilter !== "undefined") { if (typeof SelectFilter !== "undefined") {
$(".selectfilter").each(function(index, value) { $(".selectfilter").each(function(index, value) {
const namearr = value.name.split('-'); SelectFilter.init(value.id, this.dataset.fieldName, false);
SelectFilter.init(value.id, namearr[namearr.length - 1], false);
}); });
$(".selectfilterstacked").each(function(index, value) { $(".selectfilterstacked").each(function(index, value) {
const namearr = value.name.split('-'); SelectFilter.init(value.id, this.dataset.fieldName, true);
SelectFilter.init(value.id, namearr[namearr.length - 1], true);
}); });
} }
}; };

View File

@ -5,9 +5,10 @@ from django.db import models
from .models import ( from .models import (
Author, BinaryTree, CapoFamiglia, Chapter, Child, ChildModel1, ChildModel2, Author, BinaryTree, CapoFamiglia, Chapter, Child, ChildModel1, ChildModel2,
Consigliere, EditablePKBook, ExtraTerrestrial, Fashionista, FootNote, Class, Consigliere, Course, CourseProxy, CourseProxy1, CourseProxy2,
Holder, Holder2, Holder3, Holder4, Holder5, Inner, Inner2, Inner3, EditablePKBook, ExtraTerrestrial, Fashionista, FootNote, Holder, Holder2,
Inner4Stacked, Inner4Tabular, Inner5Stacked, Inner5Tabular, NonAutoPKBook, Holder3, Holder4, Holder5, Inner, Inner2, Inner3, Inner4Stacked,
Inner4Tabular, Inner5Stacked, Inner5Tabular, NonAutoPKBook,
NonAutoPKBookChild, Novel, NovelReadonlyChapter, OutfitItem, NonAutoPKBookChild, Novel, NovelReadonlyChapter, OutfitItem,
ParentModelWithCustomPk, Person, Poll, Profile, ProfileCollection, ParentModelWithCustomPk, Person, Poll, Profile, ProfileCollection,
Question, ReadOnlyInline, ShoppingWeakness, Sighting, SomeChildModel, Question, ReadOnlyInline, ShoppingWeakness, Sighting, SomeChildModel,
@ -300,6 +301,47 @@ class FashonistaStackedInline(admin.StackedInline):
model = Fashionista model = Fashionista
# Admin for #30231
class ClassStackedHorizontal(admin.StackedInline):
model = Class
extra = 1
filter_horizontal = ['person']
class ClassAdminStackedHorizontal(admin.ModelAdmin):
inlines = [ClassStackedHorizontal]
class ClassTabularHorizontal(admin.TabularInline):
model = Class
extra = 1
filter_horizontal = ['person']
class ClassAdminTabularHorizontal(admin.ModelAdmin):
inlines = [ClassTabularHorizontal]
class ClassTabularVertical(admin.TabularInline):
model = Class
extra = 1
filter_vertical = ['person']
class ClassAdminTabularVertical(admin.ModelAdmin):
inlines = [ClassTabularVertical]
class ClassStackedVertical(admin.StackedInline):
model = Class
extra = 1
filter_vertical = ['person']
class ClassAdminStackedVertical(admin.ModelAdmin):
inlines = [ClassStackedVertical]
site.register(TitleCollection, inlines=[TitleInline]) site.register(TitleCollection, inlines=[TitleInline])
# Test bug #12561 and #12778 # Test bug #12561 and #12778
# only ModelAdmin media # only ModelAdmin media
@ -327,3 +369,7 @@ site.register(Teacher, TeacherAdmin)
site.register(Chapter, inlines=[FootNoteNonEditableInlineCustomForm]) site.register(Chapter, inlines=[FootNoteNonEditableInlineCustomForm])
site.register(OutfitItem, inlines=[WeaknessInlineCustomForm]) site.register(OutfitItem, inlines=[WeaknessInlineCustomForm])
site.register(Person, inlines=[AuthorTabularInline, FashonistaStackedInline]) site.register(Person, inlines=[AuthorTabularInline, FashonistaStackedInline])
site.register(Course, ClassAdminStackedHorizontal)
site.register(CourseProxy, ClassAdminStackedVertical)
site.register(CourseProxy1, ClassAdminTabularVertical)
site.register(CourseProxy2, ClassAdminTabularHorizontal)

View File

@ -294,6 +294,38 @@ class SomeChildModel(models.Model):
parent = models.ForeignKey(SomeParentModel, models.CASCADE) parent = models.ForeignKey(SomeParentModel, models.CASCADE)
readonly_field = models.CharField(max_length=1) readonly_field = models.CharField(max_length=1)
# Models for #30231
class Course(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Class(models.Model):
person = models.ManyToManyField(Person, verbose_name='attendant')
course = models.ForeignKey(Course, on_delete=models.CASCADE)
class CourseProxy(Course):
class Meta:
proxy = True
class CourseProxy1(Course):
class Meta:
proxy = True
class CourseProxy2(Course):
class Meta:
proxy = True
# Other models # Other models

View File

@ -1356,3 +1356,37 @@ class SeleniumTests(AdminSeleniumTestCase):
self.assertEqual( self.assertEqual(
len(self.selenium.find_elements_by_css_selector(tabular_inline_formset_selector)), 1 len(self.selenium.find_elements_by_css_selector(tabular_inline_formset_selector)), 1
) )
def test_inlines_verbose_name(self):
"""
The item added by the "Add another XXX" link must use the correct
verbose_name in the inline form.
"""
self.admin_login(username='super', password='secret')
# Each combination of horizontal/vertical fiter with stacked/tabular
# inlines.
tests = [
'admin:admin_inlines_course_add',
'admin:admin_inlines_courseproxy_add',
'admin:admin_inlines_courseproxy1_add',
'admin:admin_inlines_courseproxy2_add',
]
css_selector = '.dynamic-class_set#class_set-%s h2'
for url_name in tests:
with self.subTest(url=url_name):
self.selenium.get(self.live_server_url + reverse(url_name))
# First inline shows the verbose_name.
available, chosen = self.selenium.find_elements_by_css_selector(css_selector % 0)
self.assertEqual(available.text, 'AVAILABLE ATTENDANT')
self.assertEqual(chosen.text, 'CHOSEN ATTENDANT')
# Added inline should also have the correct verbose_name.
self.selenium.find_element_by_link_text('Add another Class').click()
available, chosen = self.selenium.find_elements_by_css_selector(css_selector % 1)
self.assertEqual(available.text, 'AVAILABLE ATTENDANT')
self.assertEqual(chosen.text, 'CHOSEN ATTENDANT')
# Third inline should also have the correct verbose_name.
self.selenium.find_element_by_link_text('Add another Class').click()
available, chosen = self.selenium.find_elements_by_css_selector(css_selector % 2)
self.assertEqual(available.text, 'AVAILABLE ATTENDANT')
self.assertEqual(chosen.text, 'CHOSEN ATTENDANT')