当 Django Admin Popup(添加、更新、删除)完成时,有没有办法调用 Javascript 函数?

Posted

技术标签:

【中文标题】当 Django Admin Popup(添加、更新、删除)完成时,有没有办法调用 Javascript 函数?【英文标题】:Is there way to call a Javascript function when a Django Admin Popup (Add, Update, Delete) completes? 【发布时间】:2021-02-27 01:10:18 【问题描述】:

我有这种情况,我在 Person 字段上绑定了 change 事件。

每次选择值更改时,我们都依赖一些 javascript 来运行。它当前正在侦听所述元素的更改事件,当用户直接在 select 建议的菜单中单击一个值时,它可以正常工作。

遗憾的是,当通过 Admin Popup 功能填充此选择时,似乎不会为选择触发更改事件,因为我们的回调未执行,即使元素的值实际上已更改。

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

【问题讨论】:

在编辑选定对象(铅笔按钮)或添加新对象(+ 按钮)或两者时是否未触发 change 事件? @AntoinePinsard 是的,没有触发更改事件,但是当我从现有下拉列表中更改值时,它工作正常。 [链接] (***.com/questions/33789528/…) 这里找到了一个类似的解决方案,但没有找到详细解释 是否可以共享底层代码?如果是这样,您可能会获得有关该问题的一些额外反馈。 【参考方案1】:

如果有人想要添加、更新和删除的完整解决方案:

window.djangoDismissChangeRelatedObjectPopup = window.dismissChangeRelatedObjectPopup;

window.dismissChangeRelatedObjectPopup = function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) 
    const id = win.name.replace(/^edit_/, '');
    const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
    const selects = $(selectsSelector);
    window.djangoDismissChangeRelatedObjectPopup(win, objId, newRepr, newId);
    selects.trigger('change');
;

window.ORIGINAL_dismissAddRelatedObjectPopup = window.dismissAddRelatedObjectPopup;
window.dismissAddRelatedObjectPopup = function(win, newId, newRepr) 
    ORIGINAL_dismissAddRelatedObjectPopup(win, newId, newRepr);
    const name = win.name;
    const elem = document.getElementById(name);
    $(elem).trigger('change');
;

window.ORIGINAL_dismissDeleteRelatedObjectPopup = window.dismissDeleteRelatedObjectPopup;
window.dismissDeleteRelatedObjectPopup = function(win, objId) 
    ORIGINAL_dismissDeleteRelatedObjectPopup(win, objId);
    const id = win.name.replace(/^delete_/, '');
    const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
    const selects = $(selectsSelector);
    selects.trigger('change');

【讨论】:

【参考方案2】:

正如您在django source code 中所见,更新相关对象时不会触发change 事件。当它在deleting 和adding 上触发时。

我最初认为这是一个错误,但实际上它是有道理的,因为该值不一定/实际上已更新。

但是,如果您需要在用例中触发此类事件,这确实是一个问题。我能建议的最好的方法是在你自己的 JS 中覆盖这种行为(当然,请确保在 Django 的 JS 加载后调用它):

window.djangoDismissChangeRelatedObjectPopup = window.dismissChangeRelatedObjectPopup;

window.dismissChangeRelatedObjectPopup = function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) 
    const id = win.name.replace(/^edit_/, '');
    const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
    const selects = $(selectsSelector);
    window.djangoDismissChangeRelatedObjectPopup(win, objId, newRepr, newId);
    selects.trigger('change');

因此,每当更新相关对象时,都应该触发 change 事件。

【讨论】:

您的解决方案适用于更新对象。尽管在删除和添加时触发了更改,但这似乎不起作用。我必须添加类似的功能来添加和删除作品,现在一切正常。感谢您的帮助。

以上是关于当 Django Admin Popup(添加、更新、删除)完成时,有没有办法调用 Javascript 函数?的主要内容,如果未能解决你的问题,请参考以下文章

python之路_popup功能实现实例

Django Admin后台管理

popUp

Django Admin源码流程

很多外键 - Django Admin

添加新 *Inline 时如何在 django admin 中使用 jQuery 绑定事件