Browse Source

Fixed #28357 -- Fixed ModelAdmin.prepopulated_fields on newly added stacked inline.

Thanks Jakob Köhler for the initial patch.
Shubh1815 3 years ago
parent
commit
bb223c6f78

+ 7 - 1
django/contrib/admin/static/admin/js/inlines.js

@@ -296,7 +296,13 @@
                     dependency_list = input.data('dependency_list') || [],
                     dependencies = [];
                 $.each(dependency_list, function(i, field_name) {
-                    dependencies.push('#' + row.find('.form-row .field-' + field_name).find('input, select, textarea').attr('id'));
+                    // Dependency in a fieldset.
+                    let field_element = row.find('.form-row .field-' + field_name);
+                    // Dependency without a fieldset.
+                    if (!field_element.length) {
+                        field_element = row.find('.form-row.field-' + field_name);
+                    }
+                    dependencies.push('#' + field_element.find('input, select, textarea').attr('id'));
                 });
                 if (dependencies.length) {
                     input.prepopulate(dependencies, input.attr('maxlength'));

+ 5 - 1
django/contrib/admin/static/admin/js/prepopulate_init.js

@@ -3,7 +3,11 @@
     const $ = django.jQuery;
     const fields = $('#django-admin-prepopulated-fields-constants').data('prepopulatedFields');
     $.each(fields, function(index, field) {
-        $('.empty-form .form-row .field-' + field.name + ', .empty-form.form-row .field-' + field.name).addClass('prepopulated_field');
+        $(
+            '.empty-form .form-row .field-' + field.name +
+            ', .empty-form.form-row .field-' + field.name +
+            ', .empty-form .form-row.field-' + field.name
+        ).addClass('prepopulated_field');
         $(field.id).data('dependency_list', field.dependency_list).prepopulate(
             field.dependency_ids, field.maxLength, field.allowUnicode
         );

+ 15 - 1
tests/admin_views/admin.py

@@ -767,8 +767,22 @@ class RelatedPrepopulatedInline3(admin.TabularInline):
     autocomplete_fields = ['fk', 'm2m']
 
 
+class RelatedPrepopulatedStackedInlineNoFieldsets(admin.StackedInline):
+    model = RelatedPrepopulated
+    extra = 1
+    prepopulated_fields = {
+        'slug1': ['name', 'pubdate'],
+        'slug2': ['status'],
+    }
+
+
 class MainPrepopulatedAdmin(admin.ModelAdmin):
-    inlines = [RelatedPrepopulatedInline1, RelatedPrepopulatedInline2, RelatedPrepopulatedInline3]
+    inlines = [
+        RelatedPrepopulatedInline1,
+        RelatedPrepopulatedInline2,
+        RelatedPrepopulatedInline3,
+        RelatedPrepopulatedStackedInlineNoFieldsets,
+    ]
     fieldsets = (
         (None, {
             'fields': (('pubdate', 'status'), ('name', 'slug1', 'slug2', 'slug3'))

+ 28 - 2
tests/admin_views/tests.py

@@ -4611,7 +4611,7 @@ class SeleniumTests(AdminSeleniumTestCase):
         self.assertEqual(slug2, 'option-two-the-main-name-and-its-awesomeiiii')
         self.assertEqual(slug3, 'the-main-n\xe0m\xeb-and-its-aw\u03b5\u0161ome\u0131\u0131\u0131i')
 
-        # Stacked inlines ----------------------------------------------------
+        # Stacked inlines with fieldsets -------------------------------------
         # Initial inline
         self.selenium.find_element(By.ID, 'id_relatedprepopulated_set-0-pubdate').send_keys('2011-12-17')
         self.select_option('#id_relatedprepopulated_set-0-status', 'option one')
@@ -4687,6 +4687,32 @@ class SeleniumTests(AdminSeleniumTestCase):
             len(self.selenium.find_elements(By.CLASS_NAME, 'select2-selection')),
             num_initial_select2_inputs + 6
         )
+        # Stacked Inlines without fieldsets ----------------------------------
+        # Initial inline.
+        row_id = 'id_relatedprepopulated_set-4-0-'
+        self.selenium.find_element(By.ID, f'{row_id}pubdate').send_keys('2011-12-12')
+        self.select_option(f'#{row_id}status', 'option one')
+        self.selenium.find_element(By.ID, f'{row_id}name').send_keys(' sŤāÇkeð  inline !  ')
+        slug1 = self.selenium.find_element(By.ID, f'{row_id}slug1').get_attribute('value')
+        slug2 = self.selenium.find_element(By.ID, f'{row_id}slug2').get_attribute('value')
+        self.assertEqual(slug1, 'stacked-inline-2011-12-12')
+        self.assertEqual(slug2, 'option-one')
+        # Add inline.
+        self.selenium.find_elements(
+            By.LINK_TEXT,
+            'Add another Related prepopulated',
+        )[3].click()
+        row_id = 'id_relatedprepopulated_set-4-1-'
+        self.selenium.find_element(By.ID, f'{row_id}pubdate').send_keys('1999-01-20')
+        self.select_option(f'#{row_id}status', 'option two')
+        self.selenium.find_element(By.ID, f'{row_id}name').send_keys(
+            ' now you haVe anöther   sŤāÇkeð  inline with a very loooong '
+        )
+        slug1 = self.selenium.find_element(By.ID, f'{row_id}slug1').get_attribute('value')
+        slug2 = self.selenium.find_element(By.ID, f'{row_id}slug2').get_attribute('value')
+        self.assertEqual(slug1, 'now-you-have-another-stacked-inline-with-a-very-lo')
+        self.assertEqual(slug2, 'option-two')
+
         # Save and check that everything is properly stored in the database
         with self.wait_page_loaded():
             self.selenium.find_element(By.XPATH, '//input[@value="Save"]').click()
@@ -4699,7 +4725,7 @@ class SeleniumTests(AdminSeleniumTestCase):
             slug2='option-two-the-main-name-and-its-awesomeiiii',
             slug3='the-main-nàmë-and-its-awεšomeıııi',
         )
-        self.assertEqual(RelatedPrepopulated.objects.all().count(), 4)
+        self.assertEqual(RelatedPrepopulated.objects.all().count(), 6)
         RelatedPrepopulated.objects.get(
             name=' here is a sŤāÇkeð   inline !  ',
             pubdate='2011-12-17',