我在 Windows 8.1 64 位上使用 django 开发服务器。我也在用Tastypie。 mysql版本是:5.5(x86)。
我面临的问题是各种查询随机挂起。我在客户端使用 AJAX,但当我使用 django admin 时也会发生这种情况。我看到所有类似的问题都与 chrome 问题有关。但在 Firefox 上也会发生这种情况。 我的数据库是mysql。最近我安装了 SSD 驱动器,因此我所有的开发代码和数据库都位于该 SSD 上(我认为这不会有任何区别)
下面是 Firebug 中几个查询的示例。在这种情况下,第四个挂起(随机,有时是不同的)
block 引用>GET id=1">http://127.0.0.1:8000/api/v1/financialmodel/?user_id=1 200 OK 1.33s jquery....min.js GET id=1">http://127.0.0.1:8000/api/v1/strategy/?user_id=1 200 OK 1.35s jquery....min.js (line 6) GET id=1">http://127.0.0.1:8000/api/v1/currency/?user_id=1 200 OK 1.4s jquery....min.js (line 6) the next query get stuck (but this is random sometime it is another query) GET id=1">http://127.0.0.1:8000/api/v1/account/?user_id=1 jquery....min.js (line 6) GET id=1">http://127.0.0.1:8000/api/v1/bankbranch/?user_id=1 200 OK 2.62s
我尝试运行服务器:
block 引用>runserver with --nothread (or without)
没有改变任何东西。
我尝试安装//github.com/ashchristopher/django-concurrent-server 认为这可能会有所帮助,但同样的事情仍然随机地卡在各种查询上。
如果我使用 APTANA IDE 中的调试器暂停服务器,我发现服务器位于:
block 引用>SocketServer.py line 155
def _eintr_retry(func, *args): """restart a system call interrupted by EINTR""" while True: try: return func(*args) except (OSError, select.error) as e: if e.args[0] != errno.EINTR: raise
有什么想法吗? 非常感谢!
这是 jquery-2.0.3 中的 Ajax 代码行
// Do send the request // This may raise an exception which is actually // handled in jQuery.ajax (so no try/catch here) xhr.send( options.hasContent && options.data || null ); }, abort: function() { if ( callback ) { callback(); } } }; } });
这是一个加载 ui 树的函数:
function loadAccountsTree() { $.getJSON("/api/v1/account/?user__id=" + userid, function(json) { // Extracting the required JSON structure from the entire response var tree = json.objects[0]; $("#accounts-tree").jstree({ "sort" : function() { }, "json_data" : { "data" : tree }, "types" : { "max_children" : 1, "types" : { // Account type "default" : { "valid_children" : "none" }, "folder" : { "valid_children" : ["default", "folder"] } } }, "hotkeys" : { "return" : function() { var hovered = $('#accounts-tree .jstree-hovered'); if (hovered.length) { $("#accounts-tree").jstree("deselect_all"); $("#accounts-tree").jstree("select_node", hovered); } } }, "ui" : { select_multiple_modifier : false }, "contextmenu" : { // Select node when right-clicking "select_node" : true, items : {// Could be a function that should return an object like this one "ccp" : false, "create" : { "separator_before" : false, "separator_after" : true, "label" : "Create", "action" : false, "submenu" : { "create_file" : { "seperator_before" : false, "seperator_after" : false, "label" : "Account", action : function(obj) { this.create(obj, "last", { "attr" : { "rel" : "default" } }); } }, "create_folder" : { "seperator_before" : false, "seperator_after" : false, "label" : "Folder", action : function(obj) { this.create(obj, "last", { "attr" : { "rel" : "folder" } }); } } // End of "create_folder" contextmenu function } } } }, "plugins" : ["themes", "json_data", "ui", "hotkeys", "crrm", "dnd", "contextmenu", "types"] }).bind("before.jstree", function(e, data) { if (data.func === "remove") { var nodes = data.inst._get_node(null, true); for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; var nodeName = $(node).find('> a').text().substring(1); if ($(node).find('> ul').length) { alert('You need to delete all folders and accounts inside ' + nodeName + ' before deleting it.'); e.stopImmediatePropagation(); return false; } else if (!confirm("Are you sure you want to delete " + nodeName + " ?")) { e.stopImmediatePropagation(); return false; } } } }).bind("loaded.jstree", function(event, data) { // Selecting top account data.inst.select_node('> ul > li:first'); // Loading all assets for top account loadAccountAssets($("#accounts-tree > ul:first > li:first").attr("id")); loadCommissions($("#accounts-tree > ul:first > li:first").attr("id")); }).bind("create.jstree", function(e, data) { var newNode = data.rslt.obj; var verified = true; $(newNode).siblings().each(function(idx, listItem) { var siblingNode = $(listItem); if (newNode.attr("rel") !== siblingNode.attr("rel")) { verified = false; return false; } }); var isFolder; if (data.rslt.obj.attr("rel") == 'default') { isFolder = 'false'; } else { isFolder = 'true'; } if (verified) { $.ajax({ type : 'POST', // make sure you respect the same origin policy with this url: // http://en.wikipedia.org/wiki/Same_origin_policy url : '/api/v1/account/', data : JSON.stringify({ 'folder' : isFolder, 'user' : '/api/v1/user/' + userid + '/', 'parent' : '/api/v1/account/' + data.rslt.parent.attr("id") + '/', 'name' : data.rslt.name, 'type' : data.rslt.obj.attr("rel") }), contentType : "application/json", dataType : 'json', processData : false, success : function(r) { data.rslt.obj.attr("id", r.id); }, error : function(xhr, textStatus, error) { loadAccountsTree(); logErrors(xhr, textStatus, error); } }); } else { alert("Folders can contain either folders or accounts, not both at a time."); $(newNode).prev().addClass("jstree-last"); $(newNode).remove(); } }).bind("rename.jstree", function(e, data) { $.ajax({ type : 'PATCH', url : '/api/v1/account/' + data.rslt.obj.attr("id") + '/', data : JSON.stringify({ "name" : data.rslt.new_name }), dataType : 'json', contentType : 'application/json', error : function(xhr, textStatus, error) { loadAccountsTree(); logErrors(xhr, textStatus, error); } }); }).bind("remove.jstree", function(e, data) { $.ajax({ type : 'DELETE', url : '/api/v1/account/' + data.rslt.obj.attr("id") + '/' }); }).bind("select_node.jstree", function(event, data) { var currentNode = data.rslt.obj; var ui_currency = ($('#usd').hasClass('active')) ? 'usd' : 'ils'; var isFolder = currentNode.attr("rel") === "folder"; if (isFolder) { $("#account-form").slideUp(); } else { // The account is not a folder. Show account details and load its commissions. $("#account-form").slideDown(); $("#account-name").attr("value", $(currentNode).text().substring(2)); var bankId = $(currentNode).closest("li").data("bank_id"); var accountBank = (bankId) ? bankId : "None"; $("#bank").val(accountBank); $("#account-type").val($(currentNode).closest("li").data("account_type")); reloadAccountCommissions(currentNode.attr("id")); } reloadAccountAssets(isFolder, currentNode.attr("id"), ui_currency); var parents = currentNode.parents("li"); var parentsList = currentNode.children("a").text().substring(1); parents.each(function(index) { parentsList = $(this).children("a").text().substring(1) + ' > ' + parentsList; }); $("#account-title").text(currentNode.find("> a").text().substring(1) + " details"); $("#account-breadcrumbs > p").text("Accounts: " + parentsList); }).bind("move_node.jstree", function(e, data) { data.rslt.o.each(function(i) { var valid = true; var currentNode = $(this); $(currentNode).siblings().each(function(idx, listItem) { var siblingNode = $(listItem); if (currentNode.attr("rel") !== siblingNode.attr("rel")) { valid = false; return false; } }); if (valid) { $.ajax({ type : 'PATCH', url : '/api/v1/account/' + currentNode.attr("id") + '/', data : JSON.stringify({ "parent" : '/api/v1/account/' + data.rslt.np.attr("id") + '/' }), dataType : 'json', contentType : 'application/json', error : function(xhr, textStatus, error) { loadAccountsTree(); logErrors(xhr, textStatus, error); } }); } else { $(data.rslt.op).append(currentNode); $(currentNode).addClass("jstree-last"); alert("The parent folder can not contain folders and accounts at the same time."); } }); }); }); }
这是将所选帐户的所有 Assets 加载到网格中的函数(该网格有时保持“正在加载...”,当我检查服务器日志时,200 已发回,但在 Firebug 中,其中一个查询永无止境
function loadAccountAssets(accountid) { $("#pager-account-assets").empty(); var ui_currency = ($('#usd').hasClass('active')) ? 'usd' : 'ils'; $("#jqgrid-account-assets").empty().jqGrid({ url : '/api/v1/assetgrid/?user__id=' + userid + '&account__id__in=' + accountid + '&ui_currency_code=' + ui_currency, datatype : 'json', ajaxGridOptions : { contentType : "application/json" }, jsonReader : { repeatitems : false, id : "id" }, colNames : ['Account', 'Place', 'Subtype', 'Issuer', 'Price linkage', 'Interest type', 'Return net', 'Return gross', 'Maturity term', 'Maturity date', 'Symbol', 'Update', 'Update hint', 'Value', 'Currency', 'Units', 'Price', 'Description', 'FinancialModel'], // 'Issuer', 'Price linkage', 'Interest type', 'Return net', 'Return gross', 'Maturity term', 'Maturity date', 'Financialmodel', colModel : [{ name : 'Account', edittype : 'select', editoptions : { dataUrl : '/api/v1/account/?user__id=' + userid + '&folder=false', buildSelect : function(data) { var response = $.parseJSON(data); var s = '<select>'; $.each(response.objects, function(index, account) { s += '<option value="' + account.resource_uri + '">' + account.data + '</option>'; }); return s + "</select>"; } }, stype : 'select' }, buildHiddenColumn('Place', 'place', true, false, 'resource_uri', 'name'), buildHiddenColumn('Subtype', 'subtype', true, false, 'resource_uri', 'name'), buildHiddenColumn('Issuer', 'issuer', true, false, 'resource_uri', 'name'), { name : 'price_linkage', hidden : true, editable : true, edittype : 'select', editoptions : { value : 'F:Foreign Currency;M:Madad;I:ILS' }, stype : 'select', editrules : { edithidden : true } }, { name : 'Interest', hidden : true, editable : true, edittype : 'select', editoptions : { value : 'F:Fix;C:Changing;O:Other' }, stype : 'select', editrules : { edithidden : true } }, { name : 'Return Net', editable : true, editrules : { edithidden : true }, hidden : true, editoptions : { dataInit : function(element) { $(element).attr("readonly", true); } } }, { name : 'Return Gross', editable : true, editrules : { edithidden : true }, hidden : true, editoptions : { dataInit : function(element) { $(element).attr("readonly", "readonly"); } } }, { name : 'Maturity', hidden : true, editable : true, edittype : 'select', editoptions : { value : 'S:Short;M:Medium;L:Long' }, stype : 'select', editrules : { edithidden : true } }, { name : 'MaturityDate', hidden : true, editable : true, formatter : "date", editoptions : { dataInit : function(el) { setTimeout(function() { $(el).datepicker({ dateFormat : "yy-mm-dd" }); }, 200); } }, formoptions : { rowpos : 1, colpos : 2 }, formatoptions : { newformat : "Y-m-d" }, editrules : { edithidden : true } }, symbolColumn, { name : 'Update', edittype : 'select', editoptions : { value : 'A:Automatic;M:Manual' }, formoptions : { rowpos : 2, colpos : 2 }, stype : 'select', }, { name : 'UpdHint', formoptions : { rowpos : 3, colpos : 2 } }, { name : 'Value', width : 70, editable : false }, currencyColumn, { name : 'Units', width : 70, formoptions : { rowpos : 4, colpos : 2 }, editoptions : { dataInit : function(elem) { setTimeout(function() { // It must be an integer $(elem).numeric(false, function() { alert("Integers only"); this.value = ""; this.focus(); }); }, 100); } } }, { name : 'Price', width : 70, formoptions : { rowpos : 5, colpos : 2 }, editoptions : { dataInit : function(elem) { setTimeout(function() { $(elem).numeric(); }, 100); } } }, { name : 'Description', formoptions : { rowpos : 6, colpos : 2 }, width : 200 }, { name : 'FinancialModel', edittype : 'select', formoptions : { rowpos : 7, colpos : 2 }, editoptions : { dataUrl : '/api/v1/financialmodel/?user__id=' + userid, buildSelect : function(data) { var response = $.parseJSON(data); var s = '<select><option value="">None</option>'; $.each(response.objects, function(index, financialmodel) { s += '<option value="' + financialmodel.resource_uri + '">' + financialmodel.data + '</option>'; }); return s + "</select>"; } }, stype : 'select' }], cmTemplate : { editable : true, width : 100 }, ondblClickRow : function() { var rowid = $("#jqgrid-account-assets").getGridParam('selrow'); $('#jqgrid-account-assets').jqGrid('editRow', rowid, { keys : true, dataType : 'json', url : '/api/v1/assetgrid/' + encodeURIComponent(rowid) + '/', mtype : 'PATCH' }); }, serializeRowData : function(data) { return serializeAssetData(data); }, ajaxRowOptions : { contentType : "application/json" }, width : 835, shrinkToFit : false, gridview : true, height : "auto", autoencode : true, loadonce : true, rowNum : 10, rowList : [10, 20, 30], pager : "#pager-account-assets", viewrecords : true, }).jqGrid("navGrid", "#pager-account-assets", { search : false, refresh : false }, // edit options { closeAfterEdit : true, mtype : "PUT", serializeEditData : function(data) { return serializeAssetData(data); }, onclickSubmit : function(params, postdata) { params.url = '/api/v1/assetgrid/' + encodeURIComponent(postdata[this.id + "_id"]) + '/'; }, ajaxEditOptions : { contentType : "application/json", dataType : "json" }, afterSubmit : function(response, postdata) { $('#jqgrid-account-assets').setGridParam({ datatype : 'json' }).trigger('reloadGrid'); return [true, '', false]; }, beforeShowForm : function(form) { centerDialog($("#editmodjqgrid-account-assets")); } }, // add options { closeAfterAdd : true, mtype : "POST", serializeEditData : function(data) { return serializeAssetData(data); }, onclickSubmit : function(params, postdata) { params.url = '/api/v1/assetgrid/'; }, afterSubmit : function(response, postdata) { $('#jqgrid-account-assets').setGridParam({ datatype : 'json' }).trigger('reloadGrid'); return [true, '']; }, ajaxEditOptions : { contentType : "application/json", dataType : "json" }, beforeShowForm : function(form) { centerDialog($("#editmodjqgrid-account-assets")); } }, // delete options { // Delete parameters mtype : "DELETE", serializeDelData : function() { return ""; }, onclickSubmit : function(params, postdata) { params.url = '/api/v1/assetgrid/' + encodeURIComponent(postdata) + '/'; }, beforeShowForm : function(form) { centerDialog($("#delmodjqgrid-account-assets")); }, afterSubmit : function(response, postdata) { $('#jqgrid-account-assets').setGridParam({ datatype : 'json' }).trigger('reloadGrid'); return [true, '']; } }); }
最佳答案
我一直在我的 django 项目中使用 tastypie。运行起来非常顺利,我没有遇到这样的问题。 要调试此问题,请先确定问题出在哪里。请求是否到达服务器,数据库查询是否花费太多时间,数据库连接是否中断,等等,以了解数据库是否导致问题或您的 django 代码、tastypie 或 ajax 调用。
Development server log, I suppose you know already. paste it's output here so that we can get more understanding.
To check mysql log : follow How to see log files in MySQL?
You are using browser to call these api then install django-debug-toolbar, it will fetch some info. try curl also instead of browser :
curl http://127.0.0.1:8000/api/v1/account/?user_id=1
另请参阅此。 http://django-tastypie.readthedocs.org/en/latest/debugging.html
P.S:我无法发表评论,因为我现在的声誉很低。
关于jquery - Django 开发服务器在 Firefox 和 Chrome 上挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21038634/