bootstrap-table实现行内编辑不使用插件直接用query-ajax提交后端flask接收数据表格处理避坑指南-非前端专业4天呕心沥血战果

本文介绍如何使用Bootstrap Table插件实现表格的行内编辑功能,包括利用ondblclickcell事件触发编辑状态,通过AJAX提交更改并解决CSRF验证问题。

需要解决的问题:使用bootstrap-table实现行内编辑功能。

中途探索的路径:使用bootstrap-table-edit实现。

探索遇到的问题:bootstrap-table-edit和bootstrap-edittable无法正常行内编辑功能,实践中在浏览器调试界面提示new变量未定义啥的,原因大概率是bootstrap 与bootstrap-table与X-editable的版本不兼容的原因。

思想转换后的解决路径。使用bootstrap-table中的一个事件参数ondblclickcell来实现相关功能。具体代码和遇到的坑见下方的代码。下图是ondblclickcell的一个方法,内容很简单,就是检测到表格有双击的时候触发双击事件,事件的执行就是判断是否允许双击事件的列,允许则给表格元素设置contenteditable为true,也就是允许编辑,然后在离开触发事件的表格时,执行获取行数和修改后的内容,同时对修改后的内容进行对比确认,如果内容与原内容不一致,则执行保存数据的函数。

                onDblClickCell: function(field, value, row, $element) {
                    console.log(field,value,$element,row);
                    var arr = [0,'id','zfid','zfxm'];//设置数组,内容为列名
                    var a = eval('{% if current_user.is_admin or current_user.is_company %}true{%else%}false{%endif%}');
                    if(a){
                        if(arr.indexOf(field) == -1){//判断点击的那一列的列名是否属于之前设置的列,也就是不允许修改的列
                            $element.attr('contenteditable', true);
                            $element.blur(function() {
                                var index = $element.parent().data('index');
                                var tdValue = $element.html();
                                if(tdValue!=value){//如果对内容进行了修改,则启动保存功能
                                    saveData(index, field, tdValue,row);
                            }
                        }
                    )}}
                }

        第二个就是保存函数,这段代码其实很简单,但是,足足花费了我1天多的时间调试和处理,以及寻找问题。首先,通过updateCell来执行更新表格数据,也就是把新修改的数据保存显示到表格中,但是,这个时候的数据仅仅修改显示在前端界面,后端数据库是没有变化的,具体后端数据库如果提交修改,请继续看后面的代码。我是使用ajax通过异步提交的方式将修改后的数据实时提交到flask程序后端进行处理,这里遇到最大的坑是在csrf-token的问题上,最开始没有添加这个csrf-token的提交,所以每次提交数据都提示内部服务器错误,然后我打开这个请求后发现,具体的错误内容是csrf-token报错,也就是没有正常的提交csrf令牌导致服务器报错,因为我的flask是增加了csrf的校验,所以,所有的Post提交必须要增加csrf校验,否则是无法通过的。然后baidu上查询如何提交,最开始看的是把csrf放到data中提交,增加一个名为csrf-token,值为{{ csrf_token() }}的数据,后来发现还是报错,没有解决,又经过了一系列的查询,最后发现应该在请求头中增加校验,而且名称应该是X-CSRFToken,之前就搞错了,至于为什么前面加一个X-,我也不知道为什么,因为之前使用flask提交Post数据我也没有注意这个头部的问题。然后我就加进去了,再然后,成功提交了数据。

      第三个问题就是传递数据的类型,必须加JSON.stringify,转换数据格式后传递给后端,不然后端的处理比较麻烦。这个坑也解决了半个小时。

function saveData(index, field, value,row) {//保存函数,参数为主函数传递的修改的内容
            $('#bstable').bootstrapTable('updateCell', {//updateCell可以直接修改表格中的内容
                index: index,       //行索引
                field: field,       //列名
                value: value        //cell值

            });
            console.log({"index":row.id, "field":field,"value": value
            , "csrf_token":'{{ csrf_token() }}'});

            $.ajax({
                headers:{'Content-type':"application/json;charset=UTF-8",
                 "X-CSRFToken": '{{ csrf_token() }}'},//特别注意这里,flask开通csrf校验必须在头部增加这个字段,否则后端无法正常接收,会报错内部服务器错误500
                type: "post",
                url: "/ccxpx_edit",//这里也可以用'{{ mian.ccxpx_edit }}'视图函数名称
                data: JSON.stringify({//特别注意,flask后端要比较好处理,这里要转json再传递
                    "index":row.id,
                    "field":field,
                    "value":value
                }),
                dataType: "json",
                success: function(data){
                 console.log(data);
                 if(data.data == "success"){
                     alert('数据保存成功');
                 }},
                error:function(error){
                    console.log(error);//输出错误
                    alert('数据保存失败');
                }
            })
         }

        后端的数据看下面的图,在接收数据的时候也花费了很久的时间测试,当然,这里,接收数据还算比较好处理的问题,因为是字符串接收,所以用eval转换下,然后再通过名称获取相关的值,判断是否post提交,查询修改数据的id,然后提交修改的id,这里有个超级大的坑,目前我都还没有完全理解的一个坑,那就是无法正常提交的问题,因为提交数据的时候需要给查询的结果,也就是查询对象的相关列赋值,因为传递的是一个变量,所以最初我用的eval来执行一个赋值语句,但是总是报错,具体语言是这样的eval('q.'+ field + '=' + value),但是这个语句报错,无法执行,也就无法赋值,后来百度查询到通过q.__dict__[field] = value可以进行赋值,在flask shell中赋值后可以查询到相关的值确实改变了,但是通过db.session.commit()提交后,并没有真正的修改数据库中的值,所以我就蒙了,然后就是一天半的时间专门解决这个问题,完全不知道原因所在。

        后来发现,有一个setattr(q,field,value)语句专门批量给查询值的列传递值的,我在flask shell中测试了很久,跟q.__dict__[field] 赋值时一样的问题,也就是赋值后当时发现成功,但是commit()提交总是把数据写不进去,这个时候我快崩溃了,一万个不理解错误的原因到底在哪里,所以一天半的时间就是不断的测试测试中浪费的,后来,我想要不在系统中写进去试试,于是,下面代码中展现了现在的新的代码,再重新打开网页,居然修改成功了,所以虽然解决了问题,但是我依旧不知道原因在哪儿,奔溃。所以写下了这片文章,给有需要的人提醒一下。同时我也发现了,在flask-sqlalchemy的使用中,真的有很多很多的诀窍,比如setattr,getattr和hasattr是非常使用的几个函数,后期我会考虑把所有的提交都交给这几个函数来执行,非常非常的简单,实用,避免了写赋值代码,这也算是浪费的三四天中一个不大不小的收获吧,如果有高手知道为什么shell中提交不成功请告诉我,谢谢。

        然后具体网页修改的界面看最下面的图。

@main_bp.route('/ccxpx_edit', methods=['GET', 'POST'])
@login_required
def ccxpx_edit():

    result = {"code": "", "data": ""}
    data = eval(request.data)
    id = data.get('index')
    field = data.get('field')
    value = data.get('value')
    print('服务器接受参数', id, field, value)
    if request.method == "POST":
        if not field:
            result['data'] = '服务器未接受到参数'
            result["code"] = 400
        else:
            q = CcxpyExc.query.filter_by(id=int(id)).first()
            if q:
                #q.__dict__[field] = value
                setattr(q,field,value)
                print(q.fyccxzx)
                try:
                    db.session.commit()
                    result["code"] = 200
                    result['data'] = 'success'
                except:
                    db.session.rollback()
                    result["code"] = 300
                    result['data'] = '提交保存失败'

            else:
                result['data'] = 'id错误,未查询到数据'
                result["code"] = 444

    else:
        result["code"]=400
        result["data"]="请求方法错误"
    return jsonify(result)

       

 

 

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值