Skip to content

Commit

Permalink
Fixed #13883 -- Get 'add new item' function working
Browse files Browse the repository at this point in the history
  • Loading branch information
mmclar committed May 2, 2022
1 parent 18f0c81 commit e60d5f3
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 9 deletions.
14 changes: 14 additions & 0 deletions django/contrib/admin/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@

IS_POPUP_VAR = "_popup"
TO_FIELD_VAR = "_to_field"
SOURCE_MODEL_VAR = "_source_model"


HORIZONTAL, VERTICAL = 1, 2
Expand Down Expand Up @@ -1296,6 +1297,7 @@ def render_change_form(
"save_on_top": self.save_on_top,
"to_field_var": TO_FIELD_VAR,
"is_popup_var": IS_POPUP_VAR,
"source_model_var": SOURCE_MODEL_VAR,
"app_label": app_label,
}
)
Expand Down Expand Up @@ -1341,6 +1343,16 @@ def response_add(self, request, obj, post_url_continue=None):
# the presence of keys in request.POST.

if IS_POPUP_VAR in request.POST:
source_model_name = request.POST.get(SOURCE_MODEL_VAR)
source_model = self.model._meta.app_config.get_model(source_model_name)
fclass = self.admin_site._registry[source_model].form
f = fclass()
choices = f.fields[self.opts.verbose_name_plural].choices
for optgroup, choices in choices:
for name, choice_obj in choices:
if choice_obj == obj:
obj_optgroup = optgroup

to_field = request.POST.get(TO_FIELD_VAR)
if to_field:
attr = str(to_field)
Expand All @@ -1351,6 +1363,7 @@ def response_add(self, request, obj, post_url_continue=None):
{
"value": str(value),
"obj": str(obj),
"optgroup": obj_optgroup,
}
)
return TemplateResponse(
Expand Down Expand Up @@ -1861,6 +1874,7 @@ def _changeform_view(self, request, object_id, form_url, extra_context):
"object_id": object_id,
"original": obj,
"is_popup": IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET,
"source_model": request.GET.get(SOURCE_MODEL_VAR),
"to_field": to_field,
"media": media,
"inline_admin_formsets": inline_formsets,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
relatedWindows.forEach(function(win) {
if(!win.closed) {
win.dismissChildPopups();
win.close();
win.close();
}
});
}

function setPopupIndex() {
if(document.getElementsByName("_popup").length > 0) {
const index = window.name.lastIndexOf("__") + 2;
popupIndex = parseInt(window.name.substring(index));
popupIndex = parseInt(window.name.substring(index));
} else {
popupIndex = 0;
}
Expand Down Expand Up @@ -87,7 +87,7 @@
}
}

function dismissAddRelatedObjectPopup(win, newId, newRepr) {
function dismissAddRelatedObjectPopup(win, newId, newRepr, optgroup) {
const name = removePopupIndex(win.name);
const elem = document.getElementById(name);
if (elem) {
Expand All @@ -105,8 +105,9 @@
$(elem).trigger('change');
} else {
const toId = name + "_to";
const o = new Option(newRepr, newId);
SelectBox.add_to_cache(toId, o);
const newOption = new Option(newRepr, newId);
newOption.group = optgroup;
SelectBox.add_to_cache(toId, newOption);
SelectBox.redisplay(toId);
}
const index = relatedWindows.indexOf(win);
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/admin/static/admin/js/popup_response.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
opener.dismissDeleteRelatedObjectPopup(window, initData.value);
break;
default:
opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj);
opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj, initData.optgroup);
break;
}
}
1 change: 1 addition & 0 deletions django/contrib/admin/templates/admin/change_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1">{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">{% endif %}
{% if source_model %}<input type="hidden" name="{{ source_model_var }}" value="{{ source_model }}">{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if errors %}
<p class="errornote">
Expand Down
1 change: 1 addition & 0 deletions django/contrib/admin/views/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from django.contrib.admin.options import (
IS_POPUP_VAR,
TO_FIELD_VAR,
SOURCE_MODEL_VAR,
IncorrectLookupParameters,
)
from django.contrib.admin.utils import (
Expand Down
11 changes: 8 additions & 3 deletions django/contrib/admin/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,13 @@ def base_url_parameters(self):
return url_params_from_lookup_dict(limit_choices_to)

def url_parameters(self):
from django.contrib.admin.views.main import TO_FIELD_VAR
from django.contrib.admin.views.main import TO_FIELD_VAR, SOURCE_MODEL_VAR

params = self.base_url_parameters()
params.update({TO_FIELD_VAR: self.rel.get_related_field().name})
params.update({
TO_FIELD_VAR: self.rel.get_related_field().name,
SOURCE_MODEL_VAR: None,
})
return params

def label_and_url_for_value(self, value):
Expand Down Expand Up @@ -295,17 +298,19 @@ def get_related_url(self, info, action, *args):
)

def get_context(self, name, value, attrs):
from django.contrib.admin.views.main import IS_POPUP_VAR, TO_FIELD_VAR
from django.contrib.admin.views.main import IS_POPUP_VAR, TO_FIELD_VAR, SOURCE_MODEL_VAR

rel_opts = self.rel.model._meta
info = (rel_opts.app_label, rel_opts.model_name)
self.widget.choices = self.choices
related_field_name = self.rel.get_related_field().name
m = self.rel.field.model
url_params = "&".join(
"%s=%s" % param
for param in [
(TO_FIELD_VAR, related_field_name),
(IS_POPUP_VAR, 1),
(SOURCE_MODEL_VAR, m.__name__),
]
)
context = {
Expand Down

0 comments on commit e60d5f3

Please sign in to comment.