summaryrefslogtreecommitdiff
path: root/django/contrib/admin
diff options
context:
space:
mode:
authormgaligniana <marcelogaligniana@gmail.com>2022-04-13 15:27:21 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-04-15 07:46:37 +0200
commitc72f6f36c13a21f6db3d4f85d2d3cec87bad45e6 (patch)
tree5a97d9e0ca88e853fec2436731b1ef0dcf206d93 /django/contrib/admin
parentdeedf5bbc347e47b3be6e15783fc43a9c0a69256 (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')
-rw-r--r--django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js31
-rw-r--r--django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html2
-rw-r--r--django/contrib/admin/widgets.py1
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")