当 Django Admin Popup(绿色加号图标)完成时,是否有事件或其他方式调用 Javascript 函数?

Is there an event or another way to call a Javascript function when a Django Admin Popup (the green plus icon) completes?

假设我们有那些 Django 模型:

class Band(models.Model):
    name = models.CharField(max_length=256, default="Eagles of Death Metal")

class Song(models.Model):
    band = models.ForeignKey(Band)

当使用管理员管理这些模型时,band 字段关联到由 Django 呈现为 select html 元素的 Widget

Django 的管理员还在 select 旁边添加了一个 绿色加号图标,单击它会打开一个弹出窗口 window,用户会看到Form 添加新的乐队。单击此弹出窗口中的 保存 按钮时 window,新波段名称将保存在数据库中,并自动分配给 select 值。


每次 select 值更改时,我们都依赖一些 javascript 成为 运行。它当前正在侦听所述元素的 change 事件,当用户直接在 select.

提议的菜单中单击一个值时,它工作正常

遗憾的是,当此 select 通过 Admin Popup 功能填充时,似乎没有为 select 触发 change 事件,因为我们的回调没有执行,即使尽管元素的值实际上已更改。

是否有其他事件我们可以监听以获得与用户直接从列表中单击值时相同的行为?

这是一个 Javascript 片段,其中包含我们用来在 Django 管理员的 add/change 弹出窗口 window 被关闭时触发更改事件的 hackery。

我们在 Django 1.7 中使用它,因此它至少适用于此版本。

Monkey-patching Django admin 的 JS 方法来实现这一点并不是完成这项工作的非常优雅的方法,但它是我们发现的侵入性最小的选项。如果有人知道更好的方法,请告诉我们。

/*
 * Trigger change events when Django admin's popup window is dismissed
 */
(function($) {
    $(document).ready(function() {

        // HACK to override `dismissRelatedLookupPopup()` and
        // `dismissAddAnotherPopup()` in Django's RelatedObjectLookups.js to
        // trigger change event when an ID is selected or added via popup.
        function triggerChangeOnField(win, chosenId) {
            var name = windowname_to_id(win.name);
            var elem = document.getElementById(name);
            $(elem).change();
        }

        window.ORIGINAL_dismissRelatedLookupPopup = window.dismissRelatedLookupPopup
        window.dismissRelatedLookupPopup = function(win, chosenId) {
            ORIGINAL_dismissRelatedLookupPopup(win, chosenId);
            triggerChangeOnField(win, chosenId);
        }

        window.ORIGINAL_dismissAddAnotherPopup = window.dismissAddAnotherPopup
        window.dismissAddAnotherPopup = function(win, chosenId) {
            ORIGINAL_dismissAddAnotherPopup(win, chosenId);
            triggerChangeOnField(win, chosenId);
        }

    });
})(jQuery);