diff options
| author | mgaligniana <marcelogaligniana@gmail.com> | 2022-04-13 15:27:21 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-04-15 07:46:37 +0200 |
| commit | c72f6f36c13a21f6db3d4f85d2d3cec87bad45e6 (patch) | |
| tree | 5a97d9e0ca88e853fec2436731b1ef0dcf206d93 /django/contrib/admin | |
| parent | deedf5bbc347e47b3be6e15783fc43a9c0a69256 (diff) | |
Fixed #11803 -- Allowed admin select widgets to display new related objects.
Adjusted admin javascript to add newly created related objects to
already loaded select widgets.
In this version, applies only where limit_choices_to is not set.
Diffstat (limited to 'django/contrib/admin')
3 files changed, 33 insertions, 1 deletions
diff --git a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js index 284d44ad62..5c9c0d833d 100644 --- a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js +++ b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js @@ -87,6 +87,35 @@ } } + function updateRelatedSelectsOptions(currentSelect, win, objId, newRepr, newId) { + // After create/edit a model from the options next to the current + // select (+ or :pencil:) update ForeignKey PK of the rest of selects + // in the page. + + const path = win.location.pathname; + // Extract the model from the popup url '.../<model>/add/' or + // '.../<model>/<id>/change/' depending the action (add or change). + const modelName = path.split('/')[path.split('/').length - (objId ? 4 : 3)]; + const selectsRelated = document.querySelectorAll(`[data-model-ref="${modelName}"] select`); + + selectsRelated.forEach(function(select) { + if (currentSelect === select) { + return; + } + + let option = select.querySelector(`option[value="${objId}"]`); + + if (!option) { + option = new Option(newRepr, newId); + select.options.add(option); + return; + } + + option.textContent = newRepr; + option.value = newId; + }); + } + function dismissAddRelatedObjectPopup(win, newId, newRepr) { const name = removePopupIndex(win.name); const elem = document.getElementById(name); @@ -94,6 +123,7 @@ const elemName = elem.nodeName.toUpperCase(); if (elemName === 'SELECT') { elem.options[elem.options.length] = new Option(newRepr, newId, true, true); + updateRelatedSelectsOptions(elem, win, null, newRepr, newId); } else if (elemName === 'INPUT') { if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) { elem.value += ',' + newId; @@ -126,6 +156,7 @@ this.value = newId; } }).trigger('change'); + updateRelatedSelectsOptions(selects[0], win, objId, newRepr, newId); selects.next().find('.select2-selection__rendered').each(function() { // The element can have a clear button as a child. // Use the lastChild to modify only the displayed value. diff --git a/django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html b/django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html index 9f7e586003..6c285ea044 100644 --- a/django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html +++ b/django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html @@ -1,5 +1,5 @@ {% load i18n static %} -<div class="related-widget-wrapper"> +<div class="related-widget-wrapper" {% if not model_has_limit_choices_to %}data-model-ref="{{ model }}"{% endif %}> {{ rendered_widget }} {% block links %} {% spaceless %} diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index a361968b27..d48500e356 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -318,6 +318,7 @@ class RelatedFieldWidgetWrapper(forms.Widget): "can_change_related": self.can_change_related, "can_delete_related": self.can_delete_related, "can_view_related": self.can_view_related, + "model_has_limit_choices_to": self.rel.limit_choices_to, } if self.can_add_related: context["add_related_url"] = self.get_related_url(info, "add") |
