实习总结
前言:这篇博客主要讲下这段时间遇到的小问题。比较杂,我自已当作总结了。
真是尴尬,实习之前我是后台做的比较多,之前花了一个月较系统学了前端html,css,ajax,bootstrap这些,有兴趣可以看看我之前写的前端博客,感觉写得还可以,对初学者的话。前程明亮-前端系列。学知识嘛,能系统地学习是最好的,出现问题比较容易分析。过去一个月主要是做前端的,so 这篇博客主要写前端部分。
一、Echarts
echarts是百度开发维护的一个 可视化插件。可视化在系统开发中相当重要,比如现在公司在开发的运维系统DBMS, 监控告警系统,前端都要根据后台传的数据,利用如echarts, vis.js插件将数据可视化。啥也不多说了,直接看官网吧http://echarts.baidu.com/index.html。第一次看感觉很牛逼! 而且文档还是中文的!! 即然是中文的,肯定能看懂啦。
在看官网时,有下面的例子:

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>ECharts</title> 6 <!-- 引入 echarts.js --> 7 <script src="echarts.js"></script> 8 </head> 9 <body> 10 <!-- 为ECharts准备一个具备大小(宽高)的Dom --> 11 <div id="main" style="width: 600px;height:400px;"></div> 12 <script type="text/javascript"> 13 // 基于准备好的dom,初始化echarts实例 14 var myChart = echarts.init(document.getElementById('main')); 15 16 // 指定图表的配置项和数据 17 var option = { 18 title: { 19 text: 'ECharts 入门示例' 20 }, 21 tooltip: {}, 22 legend: { 23 data:['销量'] 24 }, 25 xAxis: { 26 data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"] 27 }, 28 yAxis: {}, 29 series: [{ 30 name: '销量', 31 type: 'bar', 32 data: [5, 20, 36, 10, 10, 20] 33 }] 34 }; 35 36 // 使用刚指定的配置项和数据显示图表。 37 myChart.setOption(option); 38 </script> 39 </body> 40 </html>
用浏览器打开如下图:
异步加载
入门示例中的数据是在初始化后setOption
中直接填入的,但是很多时候可能数据需要异步加载后再填入。ECharts
中实现异步数据的更新非常简单,在图表初始化后不管任何时候只要通过 jQuery 等工具异步获取数据后通过 setOption
填入数据和配置项就行。下面是官网的代码:
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 <script src="echarts.js"></script>
7 <script src="../bootstrap-3.3.7-dist/js/jquery-3.1.1.min.js"></script>
8 </head>
9 <body>
10 <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
11 <div id="main" style="width: 600px;height:400px;"></div>
12 <script type="text/javascript">
13
14 var myChart = echarts.init(document.getElementById('main'));
15 // 显示标题,图例和空的坐标轴
16 myChart.setOption({
17 title: {
18 text: '异步数据加载示例'
19 },
20 tooltip: {},
21 legend: {
22 data:['销量']
23 },
24 xAxis: {
25 data: []
26 },
27 yAxis: {},
28 series: [{
29 name: '销量',
30 type: 'bar',
31 data: []
32 }]
33 });
34
35 // 异步加载数据
36 $.get('data_test.json').done(function (data) {
37 // 填入数据
38 myChart.setOption({
39 xAxis: {
40 data: data.categories
41 },
42 series: [{
43 // 根据名字对应到相应的系列
44 name: '销量',
45 data: data.data
46 }]
47 });
48 });
49
50 </script>
51 </body>
52 </html>
当然,我在html文件的同级目录下,也放下data_test.json文件:上面html代码36行是通过ajax的GET请求,到data_test.json文件取数据,然后可以通过data.xxx调用json文件的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | { "categories" : [ "衬衫" , "羊毛衫" , "雪纺衫" , "裤子" , "高跟鞋" , "袜子" ], "data" : [ 5 , 20 , 36 , 10 , 10 , 20 ] } |
但是我找到HTML文件,用浏览器打开,数据加载不出来:
这就懵比了,怀疑人生。看了下浏览器的错误信息:
WEB开发过程中,很多时候我们都是写一些简单的Demo,并不是开发一个完整项目,此时我们常见的操作是:
- 新建文件夹
- 新建需要的文件
- 在Sublime(或其他编辑器)中完成DEMO的编码
- 双击HTML文件,直接在浏览器中运行演示
如果此时Demo中有AJAX操作,浏览器就会报一个错:
XMLHttpRequest cannot load file:///Users/iceStone/Documents/Learning/angular/demo/angular-moviecat/movie/view.html. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
原因很简单,浏览器(Webkit内核)的安全策略决定了file协议访问的应用无法使用XMLHttpRequest对象,错误消息中也很清楚的说明了:
Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
跨域请求仅支持协议:http, data, chrome, chrome-extension, https, chrome-extension-resource
so, 我理解上面的意思是 因为HTML文件里面有ajax方法,你直接右键html文件,用浏览器打开是无法成功执行ajax方法的。你没有类似于服务器的东西。
最后我是直接用pycharm IDE打开的本地的echarts5.html,浏览器网址如下:
看到没,本地端口63342,后面还带了一堆参数,这其实是IDE用我们的本地电脑端口开的一个端口,当作"服务端"。
二、removeClass
移除class样式,一般我们只需移除一个class, eg:hidden. 但之前有个需求,要移除一个标签两个class样式,怎么做? 查了下jquery的API,果然找到了
要从每个匹配的元素的 class 属性中移除的一个或多个 class 名称,多个 class 名称用空格分隔
三、数据库导入sql表
一天部门老大,给我发了份sql表,让我更新下,我也不知咋更新到数据库,气氛相当尴尬。
1 2 | mysql> use bigo_cmdb mysql> source / tmp / instance_meta_info.sql; |
说到底还是Linux不够6呗~_~
四、Django后台如何传数据给前端JS
这个问题是我用vis.js插件做拓扑图时遇到的,说到拓扑图,不禁得吹下牛,真得很屌,明天回公司去截个图给发上来。多个mysql之间有主从关系,我可以用箭头表示之间的关系(通过后台数据库的ID判断谁指向谁),前端我还自己写了JS生成拓扑图。有兴趣的可以留言,我可以分享部分代码。说多了,生成拓扑时我前端的javascript需要后端返回的数据,尼玛,一般是在html中获取后台返回的数据,要返回给JS,还真没遇过:
Django 数据json格式传输js
- 把一个 list 或者 dict 传递给 js文件,处理后显示到网页上, 直接在视图函数(views.py中的函数)中渲染一个 list 或 dict 的内容,和网页其它部分一起显示到网页上,一次请求一次传输。
- views.py中返回的函数中的值要用 json.dumps(xx)处理,参数xx需要字典或者列表。
- 在网页上要加一个 safe 过滤器。
大致的流程
1、第一步,在view.py渲染
1 # -*- coding: utf-8 -*- 2 from __future__ import unicode_literals 3 import json 4 from django.shortcuts import render 5 def home(request): 6 List = ['列表1', '列表2'] 7 Dict = {'键1': '值1', '键2': '值2'} 8 return render(request, 'home.html', { 9 'List': json.dumps(List), 10 'Dict': json.dumps(Dict) 11 })
2、第二步,对应需要跳转的网页home.html :
1 <script type="text/javascript"> 2 var List = {{ List|safe }};//列表 3 var Dict = {{ Dict|safe }};//字典 4 </script>
ps: 注意分号不要漏了,需要模板语言两个大括号{{ }};
可参考: http://blog.csdn.net/agly_clarlie/article/details/50551807
五、Bootstrap-select
官网移步: http://silviomoreto.github.io/bootstrap-select/examples/
我对bootstrap-select算是有一定了解。为何? 这就要从模态框说起了,因为之前是在做运维系统,涉及到很多模态框。一个月前刚入职其实都还没了解模态框这鬼东西~_~ 模态框== 弹出框(我的理解)。先来学习下模态框: 移步bootstrap官网http://v3.bootcss.com/javascript/#modals
这是我之前根据官网博客写的小demo:
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>Bootstrap 实例 - 模态框(Modal)插件</title>
6 <link rel="stylesheet" href="../bootstrap-3.3.7-dist/css/bootstrap.min.css">
7
8 </head>
9 <body>
10
11 <h2>创建模态框(Modal)</h2>
12 <!-- 按钮触发模态框 -->
13 <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
14 开始演示模态框
15 </button>
16 <!-- 模态框(Modal) -->
17 <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
18 <div class="modal-dialog">
19 <div class="modal-content">
20 <div class="modal-header">
21 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">
22 ×
23 </button>
24 <h4 class="modal-title" id="myModalLabel">
25 模态框(Modal)标题
26 </h4>
27 </div>
28 <div class="modal-body">
29 在这里添加一些文本
30 </div>
31 <div class="modal-footer">
32 <button type="button" class="btn btn-default" data-dismiss="modal">关闭
33 </button>
34 <button type="button" class="btn btn-primary">
35 提交更改
36 </button>
37 </div>
38 </div><!-- /.modal-content -->
39 </div><!-- /.modal -->
40 </div>
41
42 <script src="../bootstrap-3.3.7-dist/js/jquery-3.1.1.min.js"></script>
43 <script src="../bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
44
45 <!--
46 <script>
47 // 只需要点击 ESC 键,模态窗口即会退出。
48 $(function() {
49 $('#myModal').modal({
50 keyboard: false
51 })
52 });
53 </script>
54 -->
55
56 <script>
57 $(function() {
58 $('#myModal').modal('hide')
59 });
60 </script>
61
62 <script>
63 $(function() {
64 $('#myModal').on('hide.bs.modal',
65 function() {
66 alert('嘿,我听说您喜欢模态框...');
67 })
68 });
69 </script>
70
71 </body>
72 </html>
其实bootstrap已经封装得很牛逼了。模态框说白了就是一个div,但是它有个属性class="modal",div里面就是modal-content,通俗理解就是模态框的内容,内容又细分为三部分
- modal-header
- modal-body (modal是模态框的重点,一般用来放form表单)
- modal-footer
如果一个界面有多个模态框,你如何知道击A按钮就打开A模态框,而不是B模态框?? 很简单阿
1 | data - target = "#myModal" |
给button加上data-target属性,属性值为需要打开的模态的的ID.
.modal('show')
手动打开模态框。在模态框显示之前返回到主调函数中 (也就是,在触发 shown.bs.modal
事件之前)。
1 | $( '#myModal' ).modal( 'show' ) |
.modal('hide')
手动隐藏模态框。在模态框隐藏之前返回到主调函数中 (也就是,在触发 hidden.bs.modal
事件之前)。
$('#myModal').modal('hide')
事件
Bootstrap 的模态框类提供了一些事件用于监听并执行你自己的代码。
All modal events are fired at the modal itself (i.e. at the <div class="modal">
).
事件类型 | 描述 |
---|---|
show.bs.modal | show 方法调用之后立即触发该事件。如果是通过点击某个作为触发器的元素,则此元素可以通过事件的 relatedTarget 属性进行访问。 |
shown.bs.modal | 此事件在模态框已经显示出来(并且同时在 CSS 过渡效果完成)之后被触发。如果是通过点击某个作为触发器的元素,则此元素可以通过事件的 relatedTarget 属性进行访问。 |
hide.bs.modal | hide 方法调用之后立即触发该事件。 |
hidden.bs.modal | 此事件在模态框被隐藏(并且同时在 CSS 过渡效果完成)之后被触发。 |
loaded.bs.modal | 从远端的数据源 加载完数据之后触发该事件。 |
1 2 3 | $( '#myModal' ).on( 'hidden.bs.modal' , function (e) { / / do something... }) |
模态框学习告一段落,具体移步官网。
先回顾下原本的需求:
现在系统有一个mysql实例(包括很多信息IP, sql版本, 运维负责人....),我点击编辑按纽。比如下图:我点击按钮后弹出模态框如下图,怎么打开呢?肯定是调用一个onclick方法,JS方法里面再让模态框show一下。具体代码现在没有,明天回公司到SVN找找看。当然,不止编辑按纽,还有新增按钮,点击新增按纽也需要打开一个模态框,和下图一样布局与样式,新增的模态框的代码 复制 编辑模态框的代码就OK?傻呀,这代码太多了,所以稍微时智的方法就是新增框与编辑框用同一个模态框modal。
新增框与编辑框有不同,就是新增框form表单里面的input,select标签是没有数据的,编辑框是一调用onclick方法,前端发起Ajax方法,后台返回数据,前端再写JS给编辑框的form表单里面的input,select标签添加value。
点击编辑按:

1 function edit_instance_meta(instance_id) { 2 $.ajax({ 3 type: 'GET', 4 url: "/instanceMeta/getInstanceMetaDetail/" + instance_id, 5 data: {}, 6 success: function (callback) { 7 var obj = jQuery.parseJSON(callback)[0]; // type of obj is dict 8 console.log("obj", obj); 9 $("#edit_instance_meta").attr("action", "/instanceMeta/getInstanceMetaDetail/" + instance_id + '/'); 10 11 add_form_message(obj); 12 13 $("input[name='tel_ip']").attr("readonly","readonly"); 14 $("input[name='un_ip']").attr("readonly","readonly"); 15 $("input[name='mob_ip']").attr("readonly","readonly"); 16 $("input[name='in_ip']").attr("readonly","readonly"); 17 $("input[name='man_ip']").attr("readonly","readonly"); 18 $("input[name='login_ip']").attr("readonly","readonly"); 19 20 $('.bs-select').selectpicker('refresh'); 21 // $("textarea#filecontent").empty(); 22 23 $("#edit_instance").modal('show'); 24 25 } 26 }); 27 }
通过JS写代码给form表单,一个一个input或者select标签赋值。这种做法,优点是前后端后离,缺点是代码量太多,一个form表单你都写怎么多代码,多个form表单那还得了。

function add_form_message(obj) { $("select[name='role']").val(obj.role); $("input[name='db_port']").val(obj.db_port); $("select[name='db_type']").val(obj.db_type); $("select[name='is_weihui_machine']").val(obj.is_weihui_machine); $("select[name='backup_status']").val(obj.backup_status); $("select[name='importance_level']").val(obj.importance_level); $("input[name='business_name_desc']").val(obj.business_name_desc); $("input[name='area_num']").val(obj.area_num); $("input[name='room_num']").val(obj.room_num); $("input[name='user_name']").val(obj.user_name); $("input[name='user_passwd']").val(obj.user_passwd); $("select[name='developer']").val(obj.developer_list); $("select[name='operator_des']").val(obj.operator_des_list); $("select[name='developer_des']").val(obj.developer_des_list); $("select[name='rw_role']").val(obj.rw_role); }
清空模态框,注意用bootstrap-select后清空的方试,之前也上网了很久,网上有些方法是直接reset form来清空表单,但是我试了下,只能清空input,textarea标签,不能清空bootstrap样式的select标签!!!
1 // callback function work when modal form close 2 $('#edit_instance').on('hidden.bs.modal', function (e) { 3 4 console.log("hiddden"); 5 6 // can reset input and textarea not select 7 $("#edit_instance_meta").trigger('reset'); 8 9 // can reset select not multiple select 10 var select = $("#edit_instance_meta").find("select").each(function () { 11 this.options.selectedIndex = 0; 12 $(this).selectpicker('refresh'); 13 }); 14 15 // can reset mul select 16 var mul_select = $("#edit_instance_meta").find("select[multiple='multiple']").each(function () { 17 this.options.selectedIndex = -1; 18 $(this).selectpicker('refresh'); 19 }); 20 21 var readonly = $("#edit_instance_meta").find("input[readonly='readonly']").each(function () { 22 $(this).removeAttr("readonly"); 23 }); 24 });
先点击编辑按纽,打开模态框,关闭,再点击新增按钮,猜猜发生啥?天呐! 新增框里面有编辑框“残留”的数据。为什么呢?因为你关闭编辑模态框的时候没有清空form表单的数据。
如何清空form表单的数据,input标签很简单,令其value=""便可以,但是select标签就麻烦了。这里的select标签有使用了流行的bootstrap-select插件。待续……
六、ImportError: No module named runner
使用ansible api setup 收集服务器配置信息。公司是用python2.7 + django1.8版本开发,比较low....
from ansible.runner import Runner 出现ImportError: No module named runner
经一番折腾后发现原来是ansible版本升级后没有此模块,降为ansible 1.7.2后正常
新版本以后再折腾
七、杂
1、 Python 的内建函数 locals()
如果你是个喜欢偷懒的程序员并想让代码看起来更加简明,可以利用 Python 的内建函数 locals() 。它返回的字典对所有局部变量的名称与值进行映射。因此,前面的视图可以重写成下面这个样子:
1 2 3 | def current_datetime(request): current_date = datetime.datetime.now() return render_to_response( 'current_datetime.html' , locals ()) |
上面的代码等于下面的
1 2 3 | def current_datetime(request): now = datetime.datetime.now() return render_to_response( 'current_datetime.html' , { 'current_date' : now}) |
2、That port is already in use.
我是在Linux下用pycharm开发的,数据库的API是用本地的8000端口,有时会出现8000端口已被使用。
1 | netstat - ntlp |
It will show something like this.
1 2 3 4 5 6 7 | Active Internet connections (only servers) Proto Recv - Q Send - Q Local Address Foreign Address State PID / Program name tcp 0 0 127.0 . 0.1 : 8000 0.0 . 0.0 : * LISTEN 6599 / python tcp 0 0 127.0 . 0.1 : 27017 0.0 . 0.0 : * LISTEN - tcp 0 0 192.168 . 124.1 : 53 0.0 . 0.0 : * LISTEN - tcp 0 0 127.0 . 0.1 : 631 0.0 . 0.0 : * LISTEN - tcp6 0 0 ::: 3306 ::: * LISTEN |
So now just close the port in which Django/python running already by killing the process associated with it.
1 | kill - 9 PID |
in my case
1 | kill - 9 6599 |
Now run your Django app.
可参考:https://stackoverflow.com/questions/20239232/error-that-port-is-already-in-use
后期我没有使用模态框,在老大的建议下改用了layer弹出框,关于layer可以写的东西太多了,我打开留在下一篇博客写。下下篇博客会写表单验证,表单验证自己的折腾了很久,学习了很多验证的插件,都遇到一些问题,最后选用了jquery.validate.js插件。我自己封装了一个Layer+Jquery.validate.js+Ajax的方法,为部门开发的DBMS和监控项目节省了超多的代码。

8/12 星期六
应广大人民群众要求,特放我做的拓扑图给各位看看。有些数据不能发出来,各位将就下。
出处:http://www.cnblogs.com/0zcl
文章未标明转载则为原创博客。欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
1.非系统的学习也是在浪费时间
2.做一个会欣赏美,懂艺术,会艺术的技术人
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?