PythonStock(7):使用 dataTable+Editor+python+Tornado 实现数据通用CRUD

41 篇文章 314 订阅
30 篇文章 151 订阅

前言


使用Python开发一个股票项目。
项目地址:
https://github.com/pythonstock/stock
相关资料:
http://blog.csdn.net/freewebsys/article/category/7076584
主要使用开发语言是python。
使用的lib库是pandas,tushare,TensorFlow,tornado等。

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/78031100未经博主允许不得转载。
博主地址是:http://blog.csdn.net/freewebsys

1,使用editor编辑数据


官方demo:
https://editor.datatables.net/examples/inline-editing/simple

在股票系统中需要录入自己的股票数据,和一些字典数据表。
对这些数据表进行简单的编辑查看。不用每次都做一个CRUD,进行简单的字典表处理。
利用之前做的数据查询通用的查询显示。
代码已经上传到github上了。

最终效果:

2,增加html代码


editor = new $.fn.dataTable.Editor( {
        i18n: {
            create: {
                button: "新建",
                title:  "创建新数据",
                submit: "保存"
            },
            edit: {
                button: "修改",
                title:  "修改数据",
                submit: "保存"
            },
            remove: {
                button: "删除",
                title:  "删除数据",
                submit: "删除",
                confirm: {
                    _: "确定删除 %d 条数据?",
                    1: "确定删除 1 条数据?"
                }
            },
            error: {
                system: "发生了一系统错误,(更多信息)"
            },
            datetime: {
                previous: '前一月',
                next:     '下一月',
                months:   [ '1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月' ],
                weekdays: [ '星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六' ]
            }
        },
        ajax: "/data/editor/save?table_name={{ stockWeb.table_name }}",
        table: "#dynamic-table",
            fields: [
                {% for index,element in enumerate(stockWeb.columns) %}
                {
                    label: "{{ stockWeb.column_names[index] }}:",
                    name: "{{ element }}"
                    {% if element == "date" %} ,type: "datetime" {% end %}
                },{% end %}
            ]
        } );

        var nameParam = $.getUrlVar('table_name');
        //console.log(nameParam);
        var myTable = $('#dynamic-table').DataTable( {
            "dom": "Bfrtip",
            "bFilter": true,
            "ordering": true,
            "processing": true,
            "serverSide": true,
            "lengthMenu": [[20, 30, 50, 100,1000, -1], [20, 30, 50, 100,1000, "All"]],
            "language": {
                "url": "/static/js/datatables.Chinese.json"
            },
            "ajax": "/stock/api_data?type=editor&name="+nameParam,
            "columns": [
                {
                    "data": "",
                    "defaultContent": "",
                    "className": 'select-checkbox',
                    "orderable": true
                },
                {% for column in stockWeb.columns %}
                    { "data": "{{ column }}" },
                {% end %}
            ],
            select: {
                style:    'os',
                selector: 'td:first-child'
            },
            buttons: [
                { extend: "create", editor: editor, text: '新增' },
                { extend: "edit",   editor: editor, text: '编辑' },
                { extend: "remove", editor: editor, text: '删除' }
            ]
        } );

使用 for index,element in enumerate(stockWeb.columns) 循环将配置数据打印。

Editor 中增加了i18n 的支持,默认的是英文的。
https://editor.datatables.net/examples/simple/i18n.html
同时增加了buttons按钮。有3个按钮,【新增】,【编辑】,【删除】。
在数据的每一列里面增加了一个checkbox,选择数据之后才能进行编辑和删除操作。
而不是像其他操作那样在最后有一个编辑按钮。使用起来不是很直接。

3,后台CRUD


查询操作前面已经实现了,现在开始做的新增,修改,删除操作。

# 获得页面数据。
class SaveEditorHandler(webBase.BaseHandler):
    @gen.coroutine
    def post(self):
        action = self.get_argument("action", default=None, strip=False)
        logging.info(action)
        table_name = self.get_argument("table_name", default=None, strip=False)
        stockWeb = stock_web_dic.STOCK_WEB_DATA_MAP[table_name]
        # 临时map数组。
        param_map = {}
        # 支持多排序。使用shift+鼠标左键。
        for item, val in self.request.arguments.items():
            # 正则查找  data[1112][code] 里面的code字段
            item_key = re.search(r"\]\[(.*?)\]", item)
            if item_key:
                tmp_1 = item_key.group()
                if tmp_1:
                    tmp_1 = tmp_1.replace("][", "").replace("]", "")
                    param_map[tmp_1] = val[0].decode("utf-8")
        #logging.info(param_map)
        if action == "create":
            logging.info("###########################create")
            # 拼接where 和 update 语句。
            tmp_columns = "`, `".join(stockWeb.columns)
            tmp_values = []
            for tmp_key in stockWeb.columns:
                tmp_values.append(param_map[tmp_key])
            # 更新sql。
            tmp_values2 = "', '".join(tmp_values)
            insert_sql = " INSERT INTO %s (`%s`) VALUES('%s'); " % (stockWeb.table_name, tmp_columns, tmp_values2)
            logging.info(insert_sql)
            try:
                self.db.execute(insert_sql)
            except Exception as e:
                err = {"error": str(e)}
                logging.info(err)
                self.write(err)
                return

        elif action == "edit":
            logging.info("###########################edit")
            # 拼接where 和 update 语句。
            tmp_update = genSql(stockWeb.columns, param_map, ",")
            tmp_where = genSql(stockWeb.primary_key, param_map, "and")
            # 更新sql。
            update_sql = " UPDATE %s SET %s WHERE %s " % (stockWeb.table_name, tmp_update, tmp_where)
            logging.info(update_sql)
            try:
                self.db.execute(update_sql)
            except Exception as e:
                err = {"error": str(e)}
                logging.info(err)
                self.write(err)
                return
        elif action == "remove":
            logging.info("###########################remove")
            # 拼接where 语句。
            tmp_where = genSql(stockWeb.primary_key, param_map, "and")
            # 更新sql。
            delete_sql = " DELETE FROM %s WHERE %s " % (stockWeb.table_name, tmp_where)
            logging.info(delete_sql)
            try:
                self.db.execute(delete_sql)
            except Exception as e:
                err = {"error": str(e)}
                logging.info(err)
                self.write(err)
                return
        self.write("{\"data\":[{}]}")

在每一个操作里面都有 一个 action = self.get_argument(“action”, default=None, strip=False) 参数。用来区分3种操作。
要对数据进行sql 的拼接:
生成 INSERT INTO , UPDATE %s SET, DELETE FROM 等sql 语句。
使用self.db.execute 执行sql,并讲异常捕获,返回给前端。

效果:
错误显示

数据格式是 {“error”: “xxxx error”},datatable 会将错误的信息显示到最下面。
同时还编写了一个工具方法,拼接数据:

# 拼接sql,将value的key 和 value 放到一起。
def genSql(primary_key, param_map, join_string):
    tmp_sql = ""
    idx = 0
    for tmp_key in primary_key:
        tmp_val = param_map[tmp_key]
        if idx == 0:
            tmp_sql = " `%s` = '%s' " % (tmp_key, tmp_val)
        else:
            tmp_sql += join_string + (" `%s` = '%s' " % (tmp_key, tmp_val))
        idx += 1
    return tmp_sql

可以讲 column 字段组合起来。按照不同字符串进行join。

配置stock_web 字段:

class StockWebData:
    def __init__(self, mode, type, name, table_name, columns, column_names, primary_key, order_by):
        self.mode = mode  # 模式,query,editor 查询和编辑模式
        self.type = type
        self.name = name
        self.table_name = table_name
        self.columns = columns
        self.column_names = column_names
        self.primary_key = primary_key
        self.order_by = order_by
        if mode == "query":
            self.url = "/stock/data?table_name=" + self.table_name
        elif mode == "editor":
            self.url = "/data/editor?table_name=" + self.table_name
....

STOCK_WEB_DATA_LIST.append(
    StockWebData(
        mode="editor",
        type="股票配置管理",
        name="持仓管理",
        table_name="user_stock",
        columns=["code", "date", "price", "shares", "commission_rate", "tax_rate", "comment"],
        column_names=["股票代码", "日期", "价格", "数量", "佣金", "税率", "备注"],
        primary_key=["code", "date"],
        order_by=" code desc "
    )
)

4,总结


对datatable的研究都差不多了。有增加了数据的crud。
可以对字典数据进行CRUD,只需要配置下就可以了,节省了大部分代码。
非常的方便。

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/78031100 未经博主允许不得转载。
博主地址是:http://blog.csdn.net/freewebsys

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值