【问题标题】:Django - Reverse Engineering the Admin site's "Add Foreign Key" buttonDjango - 对管理站点的“添加外键”按钮进行逆向工程
【发布时间】:2011-12-08 14:37:31
【问题描述】:

TL;DR(简短的概要):

我在自己的项目中重新创建了管理员“添加”按钮。但是,当我在父表单上点击“保存”时,它无法识别新的选择元素。

整个故事:

我在自己的项目中拥有该功能......几乎。我需要帮助弄清楚最后一步。就像现在一样,我有一个“+”按钮,我点击它,弹出一个弹出窗口,我添加一个新对象,点击保存,弹出窗口关闭,新项目现在在我的选择框中并被选中 - 就像管理员一样页。但是,当我在这个父表单上点击保存时,我得到了我选择了一个不在列表中的项目的错误。当然,由于页面已重新加载,我的新项目 是列表的一部分,我只需再次点击保存,它就可以工作了。当然,我需要它来保存第一次!

基本设置是我的父模型称为System,外键模型称为ZoneZone 模型列出了系统有多少个区域(1 个区域、2 个区域、10 个区域等...)

好的,一些代码:

父表单模板中的“添加”链接:

<a href="/systems/zones/new/?popup=1" id="add_id_numZones" onclick="return showAddPopup(this);">Add</a>

在我的New_Zone 视图中,保存新区域后,我检查popup GET 变量是否为1,如果是,则返回一个javascript 函数。这是视图:

        ...
        if form.is_valid():
            f = form.save(commit=False)
            pk_value = f.numOfZones
            form.save()
            obj = Zone_Info.objects.get(numOfZones=pk_value)
            if isPopup == "1":
                return HttpResponse('<script>opener.closeAddPopup(window, "%s", "%s");</script>' % (escape(pk_value), escape(obj)))
        ...

这是我的 Javascript(主要从管理员 javascript 复制:

function html_unescape(text) {
// Unescape a string that was escaped using django.utils.html.escape.
    text = text.replace(/&lt;/g, '<');
    text = text.replace(/&gt;/g, '>');
    text = text.replace(/&quot;/g, '"');
    text = text.replace(/&#39;/g, "'");
    text = text.replace(/&amp;/g, '&');
    return text;
}

function windowname_to_id(text) {
    text = text.replace(/__dot__/g, '.');
    text = text.replace(/__dash__/g, '-');
    return text;
}


function showAddPopup(triggeringLink, pWin) {
    var name = triggeringLink.id.replace(/^add_/, '');
    href = triggeringLink.href;
    var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
    win.focus();
    return false;
}

function closeAddPopup(win, newID, newRepr) {
    newID = html_unescape(newID);
    newRepr = html_unescape(newRepr);
    var name = windowname_to_id(win.name);
    var elem = document.getElementById(name);
    if (elem) {
        if (elem.nodeName == 'SELECT') {
            var o = new Option(newRepr, newID);
            elem.options[elem.options.length] = o;
            o.selected = true;
        } else if (elem.nodeName == 'INPUT') {
            if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
                elem.value += ',' + newID;
            } else {
                elem.value = newID;
            }
        }
    } else {
        var toId = name + "_to";
        elem = document.getElementById(toId);
        var o = new Option(newRepr, newID);
        SelectBox.add_to_cache(toId, o);
        SelectBox.redisplay(toId);
    }

    win.close();
}

我看了this 问题,似乎我在做同样的事情。

关于如何让表单识别新的选择元素的最后一步有什么想法吗?

谢谢!

【问题讨论】:

    标签: javascript django django-models


    【解决方案1】:

    我想通了

    问题是我传递给closeAddPopup javascript 函数的内容。本质上,我是在传递垃圾值。

    这是我最初在 New_Zone 视图中看到的内容(不起作用):

        ...
        if form.is_valid():
            f = form.save(commit=False)
            pk_value = f.numOfZones
            form.save()
            obj = Zone_Info.objects.get(numOfZones=pk_value)
            if isPopup == "1":
                return HttpResponse('<script>opener.closeAddPopup(window, "%s", "%s");</script>' % (escape(pk_value), escape(obj)))
        ...
    

    这对我来说是一个非常愚蠢的错误(显然已经晚了)。我将f 分配给我认为pk 的字段numOfZones 并将其发送到脚本。

    现在,工作视图如下所示:

           if form.is_valid():
               obj = form.save()
               pk_value = obj.pk
               if "_popup" in request.REQUEST:
                   return HttpResponse('<script>opener.closeAddPopup(window, "%s", "%s");</script>' % (escape(pk_value), escape(obj)))
    

    无论如何...感谢...好吧,Stackoverflow。如果不发布问题并在 stackoverflow 上重新阅读我的代码,我认为我不会解决问题。

    【讨论】:

    猜你喜欢
    • 2013-05-30
    • 1970-01-01
    • 2013-07-31
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    • 2019-02-07
    • 2016-04-01
    相关资源
    最近更新 更多