2019独角兽企业重金招聘Python工程师标准>>>
感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正!
如有转载,请保留源作者博客信息。
如需交流,欢迎大家博客留言。
1、鉴于国内java开发人员比较多,java web方面的技术比较成熟。所以用python django(openstack)框架和java的strurs做个类比,让大家能够更直观的理解、更快的进入到开发中:


urlpatterns = patterns('', url(r'^$', views.IndexView.as_view(), name='index'), url(r'^(?P<tenant_id>[^/]+)/update/$',views.UpdateIsolationView.as_view(), name='update'), url(r'^(?P<tenant_id>[^/]+)/tree/$',views.TreeView.as_view(), name='tree'), url(r'^(?P<tenant_id>[^/]+)/get_tree_data/$',views.JSONGetView.as_view(), name='get_tree_data'), url(r'^(?P<tenant_id>[^/]+)/set_tree$',views.JSONSetView.as_view(), name='set_tree'), ) |

from django.views import generic from django.http import HttpResponse # noqa import json class JSONGetView(generic.View): def get(self, request, *args, **kwargs): #定义get方法 tenant_id = self.kwargs["tenant_id"] #从url中截取参数值tenant_id aggregates = [] try: aggregates = api.nova.aggregate_details_list(self.request) api.nova.isolatation_tree_list(self.request, tenant_id) except Exception: exceptions.handle(request, _('Unable to retrieve host aggregates list.')) aggregates.sort(key=lambda aggregate: aggregate.name.lower()) #调用底层api 构造 zTree的数据 tree_list = [] for ag in aggregates: tree_data = {} tree_data['id'] = ag.availability_zone tree_data['name'] = ag.availability_zone tree_data['pId'] = 'NULL' tree_data['open'] = 'true' if tree_data not in tree_list: tree_list.append(tree_data) tree_data = {} tree_data['id'] = ag.name tree_data['name'] = ag.name tree_data['pId'] = ag.availability_zone tree_data['open'] = 'true' if tree_data not in tree_list: tree_list.append(tree_data) for hostname in ag.hosts: tree_data = {} tree_data['id'] = hostname tree_data['name'] = hostname tree_data['pId'] = ag.name tree_data['open'] = 'true' if tree_data not in tree_list: tree_list.append(tree_data) result = json.dumps(tree_list) #此处将python对象转换成json对象 print (result) return HttpResponse(result,content_type="application/json") |

http://192.168.10.31/dashboard/admin/isolations/2a4fe5e733e44982b1d576c5a0fe4bfd/get_tree_data/ 得到数据: [{ "open": "true", "pId": "NULL", "id": "zone1", "name": "zone1" }, { "open": "true", "pId": "zone1", "id": "ag1", "name": "ag1" }, { "open": "true", "pId": "ag1", "id": "node32", "name": "node32" }, { "open": "true", "pId": "ag1", "id": "node31", "name": "node31" }, { "open": "true", "pId": "zone1", "id": "ag2", "name": "ag2" }, { "open": "true", "pId": "ag2", "id": "node33", "name": "node33" }, { "open": "true", "pId": "NULL", "id": "zone2", "name": "zone2" }, { "open": "true", "pId": "zone2", "id": "ag3", "name": "ag3" }, { "open": "true", "pId": "ag3", "id": "node35", "name": "node35" }, { "open": "true", "pId": "ag3", "id": "node34", "name": "node34" }] |



{# add by ttx 2014-9-25#} <link rel="stylesheet" href="{{ STATIC_URL }}dashboard/js/zTree/css/demo.css" type="text/css"> <link rel="stylesheet" href="{{ STATIC_URL }}dashboard/js/zTree/css/zTreeStyle/zTreeStyle.css" type="text/css"> <script type="text/javascript" src="{{ STATIC_URL }}dashboard/js/zTree/js/jquery.ztree.core-3.5.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}dashboard/js/zTree/js/jquery.ztree.excheck-3.5.js"></script> |

var url = '/dashboard/admin/isolations/{{ tenant_id }}/get_tree_data'; #此处为ajax的url地址,与步骤4中浏览器访问一致 $.ajax({ #其中$代表Jquery插件,ajax为Jquery插件的方法 type: "get", #type主要有get、post。其中get用于获取数据,是幂等操作、post用于跟新数据 async: false, #false代码同步刷新,true代表异步刷新。本示例需要等到数据返回再进行tree的渲染,因此需要同步 url: url, #请求的url地址 dataType: "json", #数据返回类型为json success: function (data) { #ajax请求成功之后得到数据data,执行success:后面function里面代码 json = JSON.stringify(data); host_tree_data = JSON.parse(json) } }); 更多ajax详细使用讲解请自行参考相关资料。 |
{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% load url from future %} {% block form_id %}create_image_form{% endblock %} {% block form_action %}{% url 'horizon:admin:images:create' %}{% endblock %} {% block form_attrs %}enctype="multipart/form-data"{% endblock %} {% block modal-header %}{% trans "Isolatation tree" %}{% endblock %} {% block modal-body %} <SCRIPT type="text/javascript"> <!-- var setting = { view: { selectedMulti: false }, check: { enable: true }, data: { simpleData: { enable: true } }, callback: { beforeCheck: beforeCheck, onCheck: onCheck } }; var code, log, className = "dark"; function beforeCheck(treeId, treeNode) { className = (className === "dark" ? "":"dark"); showLog("[ "+getTime()+" beforeCheck ] " + treeNode.name ); return (treeNode.doCheck !== false); } function onCheck(e, treeId, treeNode) { showLog("[ "+getTime()+" onCheck ] " + treeNode.name ); getAllChangeNodes() } function getAllChangeNodes() { var treeObj = $.fn.zTree.getZTreeObj("treeDemo"); var nodes = treeObj.getChangeCheckedNodes(); $('#mytest').html(JSON.stringify(nodes)); var url = '/dashboard/admin/isolations/{{ tenant_id }}/set_tree'; var data={}; data["jsonTree"] = JSON.stringify(nodes); jQuery.ajax({ type:"POST", url : url, data:data, dataType : "json", beforeSend: function(xhr, settings){ var csrftoken = $.cookie('csrftoken'); xhr.setRequestHeader("X-CSRFToken", csrftoken); }, success : function(data) { } }); } function showLog(str) { if (!log) log = $("#log"); log.append("<li class='"+className+"'>"+str+"</li>"); if(log.children("li").length > 6) { log.get(0).removeChild(log.children("li")[0]); } } function getTime() { var now= new Date(), h=now.getHours(), m=now.getMinutes(), s=now.getSeconds(), ms=now.getMilliseconds(); return (h+":"+m+":"+s+ " " +ms); } function checkNode(e) { var zTree = $.fn.zTree.getZTreeObj("treeDemo"), type = e.data.type, nodes = zTree.getSelectedNodes(); if (type.indexOf("All")<0 && nodes.length == 0) { alert("请先选择一个节点"); } if (type == "checkAllTrue") { zTree.checkAllNodes(true); } else if (type == "checkAllFalse") { zTree.checkAllNodes(false); } else { var callbackFlag = $("#callbackTrigger").attr("checked"); for (var i=0, l=nodes.length; i<l; i++) { if (type == "checkTrue") { zTree.checkNode(nodes[i], true, false, callbackFlag); } else if (type == "checkFalse") { zTree.checkNode(nodes[i], false, false, callbackFlag); } else if (type == "toggle") { zTree.checkNode(nodes[i], null, false, callbackFlag); }else if (type == "checkTruePS") { zTree.checkNode(nodes[i], true, true, callbackFlag); } else if (type == "checkFalsePS") { zTree.checkNode(nodes[i], false, true, callbackFlag); } else if (type == "togglePS") { zTree.checkNode(nodes[i], null, true, callbackFlag); } } } } function setAutoTrigger(e) { var zTree = $.fn.zTree.getZTreeObj("treeDemo"); zTree.setting.check.autoCheckTrigger = $("#autoCallbackTrigger").attr("checked"); $("#autoCheckTriggerValue").html(zTree.setting.check.autoCheckTrigger ? "true" : "false"); } $(document).ready(function(){ var url = '/dashboard/admin/isolations/{{ tenant_id }}/get_tree_data'; $.ajax({ type: "get", async: false, url: url, dataType: "json", success: function (data) { json = JSON.stringify(data); host_tree_data = JSON.parse(json) } }); var zNodes =[ { id:1, pId:0, name:"1", open:true}, { id:11, pId:1, name:"1-1"}, { id:12, pId:1, name:"1-2"}, { id:111, pId:11, name:"1-1-1","checked":"true"}, { id:112, pId:11, name:"1-1-2"}, ]; $.fn.zTree.init($("#treeDemo"), setting, host_tree_data); $("#checkTrue").bind("click", {type:"checkTrue"}, checkNode); $("#checkFalse").bind("click", {type:"checkFalse"}, checkNode); $("#toggle").bind("click", {type:"toggle"}, checkNode); $("#checkTruePS").bind("click", {type:"checkTruePS"}, checkNode); $("#checkFalsePS").bind("click", {type:"checkFalsePS"}, checkNode); $("#togglePS").bind("click", {type:"togglePS"}, checkNode); $("#checkAllTrue").bind("click", {type:"checkAllTrue"}, checkNode); $("#checkAllFalse").bind("click", {type:"checkAllFalse"}, checkNode); $("#autoCallbackTrigger").bind("change", {}, setAutoTrigger); }); //--> </SCRIPT> <h1>用 zTree 方法 勾选 checkbox</h1> <h6>[ 文件路径: excheck/checkbox_fun.html ]</h6> <div class="content_wrap"> <div class="zTreeDemoBackground left"> <ul id="treeDemo" class="ztree"></ul> </div> </div> <div> <ul class="info"> <div id="mytest">11111111111111111111111111111111111111111111</div> <li class="title"><h2>1、beforeCheck / onCheck 事件回调函数控制</h2> <ul class="list"> <li>利用 beforeCheck / onCheck 事件回调函数 可以控制是否允许 更改 节点勾选状态,这里简单演示如何监控此事件</li> <li><p>这里还演示了 checkNode / checkAllNodes 方法触发 beforeCheck / onCheck 事件回调函数的情况,试试看:<br/> <input type="checkbox" id="autoCallbackTrigger" /> setting.check.autoCheckTrigger: <span id="autoCheckTriggerValue">false</span><br/> <input type="checkbox" id="callbackTrigger" checked /> 执行勾选方法是否触发 callback <br/> 单节点--[ <a id="checkTrue" href="#" title="不想勾选我就不勾选你..." οnclick="return false;">勾选</a> ] [ <a id="checkFalse" href="#" title="不想取消勾选我就不取消你..." οnclick="return false;">取消勾选</a> ] [ <a id="toggle" href="#" title="你想怎样?..." οnclick="return false;">勾选 切换</a> ]<br/> 单节点 ( 影响父子 )--[ <a id="checkTruePS" href="#" title="不想勾选我就不勾选你..." οnclick="return false;">勾选</a> ] [ <a id="checkFalsePS" href="#" title="不想取消勾选我就不取消你..." οnclick="return false;">取消勾选</a> ] [ <a id="togglePS" href="#" title="你想怎样?..." οnclick="return false;">勾选 切换</a> ]<br/> 全部节点--[ <a id="checkAllTrue" href="#" title="不管你有多NB,统统都要听我的!!" οnclick="return false;">勾选</a> ] [ <a id="checkAllFalse" href="#" title="不管你有多NB,统统都要听我的!!" οnclick="return false;">取消勾选</a> ]</p> </li> <li><p><span class="highlight_red">使用 zTreeObj.checkNode / checkAllNodes 方法,详细请参见 API 文档中的相关内容</span><br/> beforeCheck / onCheck log:<br/> <ul id="log" class="log" style="height:130px;"></ul></p> </li> </ul> </li> <li class="title"><h2>2、setting 配置信息说明</h2> <ul class="list"> <li>同 "checkbox 勾选操作" 中的说明</li> </ul> </li> <li class="title"><h2>3、treeNode 节点数据说明</h2> <ul class="list"> <li>同 "checkbox 勾选操作" 中的说明</li> </ul> </li> </ul> </div> {% endblock %} {% block modal-footer %} <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save" %}" /> <a href="{% url 'horizon:admin:images:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a> {% endblock %} |
![]() |


function getAllChangeNodes() { var treeObj = $.fn.zTree.getZTreeObj("treeDemo"); var nodes = treeObj.getChangeCheckedNodes(); $('#mytest').html(JSON.stringify(nodes)); #JSON.stringify(nodes)将js对象nodes,转化为json对象 var url = '/dashboard/admin/isolations/{{ tenant_id }}/set_tree'; var data={}; #url中传递的数据,相当于$url?jsonTree=JSON.stringify(nodes) data["jsonTree"] = JSON.stringify(nodes); jQuery.ajax({ type:"POST", #ajax类型,post进来进行更新 url : url, data:data, dataType : "json", beforeSend: function(xhr, settings){ #此处的beforeSend用来解决ajax在django中报csrftoken错误 var csrftoken = $.cookie('csrftoken'); xhr.setRequestHeader("X-CSRFToken", csrftoken); }, success : function(data) { #ajax请求成功之后执行 } }); } |

urlpatterns = patterns('', url(r'^$', views.IndexView.as_view(), name='index'), url(r'^(?P<tenant_id>[^/]+)/update/$',views.UpdateIsolationView.as_view(), name='update'), url(r'^(?P<tenant_id>[^/]+)/tree/$',views.TreeView.as_view(), name='tree'), url(r'^(?P<tenant_id>[^/]+)/get_tree_data/$',views.JSONGetView.as_view(), name='get_tree_data'), url(r'^(?P<tenant_id>[^/]+)/set_tree$',views.JSONSetView.as_view(), name='set_tree'), ) |

class JSONSetView(generic.View): def post(self, request, *args, **kwargs): #因为ajax的请求类型为post因此实现post函数,否则会报错 tenant_id = self.kwargs["tenant_id"] #从URL中获取tenant_id json_tree = request.POST.get("jsonTree") #从ajax发过来的请求中获取jsonTree json数据 tree_change_nodes = json.loads(json_tree) #将页面传递的json数据,转换为python对象,具体转换规则自行参考 #此处根据前端传送的数据,调用api传递给后端处理 api.nova.isolatation_add_tree(request, tenant_id, tree_change_nodes) return HttpResponse(tree_change_nodes,content_type="application/json") |