test: 博客美化中……

实习总结

前言:这篇博客主要讲下这段时间遇到的小问题。比较杂,我自已当作总结了。

真是尴尬,实习之前我是后台做的比较多,之前花了一个月较系统学了前端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>
View Code

用浏览器打开如下图:

异步加载

入门示例中的数据是在初始化后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文件的数据。

{
    "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表,让我更新下,我也不知咋更新到数据库,气氛相当尴尬。

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                     &times;
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模态框?? 很简单阿

data-target="#myModal"

给button加上data-target属性,属性值为需要打开的模态的的ID.

手动打开模态框。在模态框显示之前返回到主调函数中 (也就是,在触发 shown.bs.modal 事件之前)。

$('#myModal').modal('show')

手动隐藏模态框。在模态框隐藏之前返回到主调函数中 (也就是,在触发 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 远端的数据源加载完数据之后触发该事件。
$('#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 }
View Code

通过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);
}
View Code

清空模态框,注意用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() 。它返回的字典对所有局部变量的名称与值进行映射。因此,前面的视图可以重写成下面这个样子:

def current_datetime(request):
    current_date = datetime.datetime.now()
    return render_to_response('current_datetime.html', locals())

上面的代码等于下面的

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端口已被使用。

netstat -ntlp

It will show something like this.

   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.

kill -9 PID

in my case

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和监控项目节省了超多的代码。

View Code

 

8/12  星期六

应广大人民群众要求,特放我做的拓扑图给各位看看。有些数据不能发出来,各位将就下。

 

 

 

posted @ 2017-08-12 00:47  前程明亮  阅读(2377)  评论(4编辑  收藏  举报