Django - jquery:根据另一个组合框的选择填充组合框

时间:2011-08-22 13:39:28

标签: django jquery django-forms

我对Django和jquery很新。我正在尝试根据在另一个comboBox中选择的选项填充comboBox(Django中的ChoiceField)(无需重新加载页面)。

我找不到ajax这种基本应用的任何简单例子。

现在,当我从第一个下拉列表中选择一个项目时,我会调用以下ajax函数。

function get_asset_from_type(){
        var type_asset = $("#id_type").val();
        var data = {type_asset:type_asset};
        var args = {type:"POST", url:"/asset/etatType/", data:data};
        $.ajax(args);

        alert(type_asset);

        return false;
};

它会警告正确的类型,但在给定的网址上会出现403错误。奇怪的是这个url在我第一次加载页面时工作。我不明白发生了什么......

编辑: 403错误似乎消失了,仍然是最初的问题:)

1 个答案:

答案 0 :(得分:2)

我认为你遇到了CSRF问题。因为Django默认阻止没有带有403的CSRF令牌的POST请求。在JS中有几种方法可以解决这个问题。一种是从cookie中提取值,可以在此处找到执行此操作的代码:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

或者您可以通过使用javascript脚本标记传递CSRF_TOKEN来执行此操作:

<script src='myjavascript.js?CSRF_TOKEN={{ csrf_token }}'></script>

请注意,它使用的是双braket,而不是{%%}。这将获取令牌的值,而不是表单输入。

function getOptionsFromScriptSrc() {
    // Get last script tag in parsed DOM.
    // Due to the way html pages are parsed, 
    // the last one is always the one being loaded.

    var options = {}
    var js_src = $('script').last().attr('src');

    if(js_src.match(/\?/)) {
        var options_list = js_src.split('?')[1].split('&');
        for(var i = 0; i < options_list.length; i++) {
            var tmp = options_list[i].split('=');
            options[$.trim(tmp[0])] = $.trim(tmp[1]);
        }
    }

    return options;
}

function get_asset_from_type(){
    var options = getOptionsFromScriptSrc();
    var type_asset = $("#id_type").val();
    var data = {type_asset: type_asset, csrfmiddlewaretoken: options['CSRF_TOKEN']};
    var args = {type:"POST", url:"/asset/etatType/", data:data};
    $.ajax(args);

    alert(type_asset);

    return false;
};

我当然没有测试过这段代码,但之前我已经使用过这种方法而且效果很好。


对于填充选择框的主要问题,您需要为ajax帖子指定回调,然后处理从服务器返回的数据:

function get_asset_from_type(){
    var options = getOptionsFromScriptSrc();
    var type_asset = $("#id_type").val();
    var post_data = {type_asset: type_asset, csrfmiddlewaretoken: options['CSRF_TOKEN']};

    $.post('/asset/etatType/', post_data, function(data){
        // Assuming server is going to respond with the html of the options, eg: <option value="1">One</option><option value="2">Two</option>...
        $('#id_ofmyselectbox').append(data);
    }); 
};