Django之CURD插件

什么是CURD?

CURD顾名思义就是create,update,rearch,delete(所谓的增删改查).

当我们接到一个项目的时候,夸夸夸的就写完表结构,然后就一直写增删改查,增删改查,写了一个月,看似很认真效率很高,但是这里我要严肃的告诉你。你只需要一个配置文件就可以完成对表进行增删改查.什么???你不信??and那么看看。

1.配置文件

配置文件需要放上面?

1.confi [{'q':数据库的字段名,

    'title':表单的head名

    'display' :1/0 是否可以显示

    text:{content:.....

      kwargs:{......}}}]

2.数据库内容

3.全局变量,主要针对的是choice

4.分页

        msg={
            'config':config,
            'data_list':list(data_list),
            'global_dict':{
                'user_choice':models.UserInfo.user_choice,
            },
            'page_str':page_str,
        }


 config = [
            {
                'q': None,
                'title': '选项',
                'display': 1,
                'text': {
                    'content':'<input type="checkbox"/>'
                },
                'attrs': {},
            },
            {
                'q': 'id',
                'title': 'ID',
                'display': 0,
                'text':None,
                'attrs': {},
            },
            {
                'q': 'username',
                'title': '姓名',
                'display': 1,
                'text':{'content':'{username}',
                        'kwargs':{'username':'@username'}},
                'attrs': {'edit-enalbe':'true','edit-type':'input',
                          'name':'username','origin':'@username'},
            },
            {
                'q': 'user_type',
                'title': '用户类型',
                'display': 1,
                'text': {'content': '{n}',
                         #               @@ 后面的数据是要选择的元组
                         #                和一个@的区分开
                         'kwargs': {'n': '@@user_choice'}},
                'attrs': {'edit-enalbe':'true', 'edit-type':'select'
                           ,'global-name':'user_choice','origin':'@user_type',
                          'name':'user_type'},
            },
            {
                'q': 'nickname',
                'title': '昵称',
                'display': 1,
                'text': {'content': '{nick}',
                         'kwargs': {'nick': '@nickname'}},
                'attrs': {'edit-enalbe': 'true', 'edit-type': 'input',
                          'name':'nickname','origin':'@nickname'},

            },
            {
                'q': 'user2blog__surfix',
                'title': '博客地址',
                'display': 1,
                'text': {'content': '{n}',
                         'kwargs': {'n': '@user2blog__surfix'}},
                'attrs': {'edit-enalbe':'fault'},

            },
            {
                'q': None,
                'title': '操作',
                'display': 1,
                'text': {'content': '<a href="/index-{nid}">{m}</a>',
                         'kwargs': {'nid': '@id',"m":'查看详细'}},
                'attrs': {},
            },
        ]

从上面可以看出来,我们根据q为字段去数据库中拿数据

q_list =[]
        for item in config:
            if not item['q']:
                continue
            q_list.append(item['q'])
        data_list_count = models.UserInfo.objects.all().values(*q_list)

放在列表里面的是我们想要拿到的数据库字段名数据.

操作没有数据则q为None

2.初始化table的head

  function initHead(config) {
        $('#talbe_th').empty();
        var tr = $('<tr></tr>');
        $.each(config,function (k,v) {
            if (v.display){
                var th=$('<th></th>');
                th.html(v.title);
                tr.append(th)
            }
        });

3.{}的格式化

在配置文件中可以看到,conten:'{username}-{id}'

{}里面只的是我们需要格式化的内容,js没有格式化的函数,那么需要我们自定制.

    String.prototype.format = function (kwargs) {
        var ret = this.replace(/\{(\w+)\}/g,function (km,m) {
//               {username}-{id}
//                匹配成功后,km等于{username}和{id}, m等于 username和id
//                'kwargs':{'username':'chenxuming','id':'1'}}
            return kwargs[m]
                            });
        return ret
    };

通过自定制,我们可以用.format方法进行格式化.

4.一个@

配置文件中有一个@的符号的代表取数据库中的数据.

如何取?

**思路**

嵌套三层循环

1.第一层:

数据库取到的数据循环,主要是循环取到数据库的行数........行用一个tr标签

2.第二层,循环配置文件的config列表,列表嵌套了多个字典

每一个字典创建一个td标签

因为每一行都要有n列数据,字典里就有n个需要循环遍历.

3.第三层循环: 循环每一个config_values里的kwargs('kwargs':{'username':'@username','id':'@id'}) 将带@符号的kwargs字典值替换数据库的值,没带的则不对应放在新的字典里 new_kwargs 最后将new_kwargs进行格式化转换

function initBody(config,data_list) {
        $("#table_tb").empty();

//       第一层
 $.each(data_list,function (data_key,data_values) {
            var tr = $('<tr></tr>');
            tr.attr('row-id',data_values['id']);

//           第二层,循环配置文件的config列表
//                 一个字典里:  {
//               'q': 'username',
//               'title': '姓名',
//               'display': 1,
//               'text':{'content':'{username}-{id}',
//                       'kwargs':{'username':'@username','id':'@id'}
        $.each(config,function (config_key,config_values) {
            if (config_values.display){
                var new_kwargs={};
                var td=$('<td></td>');

//                   第三层
$.each(config_values.text.kwargs,function (key,values) {else if (values[0]=='@'){
//                                 有一个@的代表去数据库的值
                                new_kwargs[key] = data_values[values.substring(1,values.length)];
                            }
                            else{
                                new_kwargs[key] = values
                            }
                            }
                            );
                var temp = config_values.text.content.format(new_kwargs);
                    td.html(temp);
                    tr.append(td)
                }
                            });
            $("#table_tb").append(tr);

        })
    }

这里执行了initBody(config,data_list)初始化了body

5.两个@

有两个@的代表了在choice取数据,编辑的时候生成select框.

**思路**

1,在config里@@后面的内容是choice存放元组的字段名,而''q''里存放的是choice选择的字段名.Intergerfile)

{
                'q': 'user_type',
                'title': '用户类型',
                'display': 1,
                'text': {'content': '{n}',
                         #               @@ 后面的数据是要选择的元组
                         #                和一个@的区分开
                         'kwargs': {'n': '@@user_choice'}},
                'attrs': {'edit-enalbe':'true', 'edit-type':'select'
                           ,'global-name':'user_choice','origin':'@user_type',
                          'name':'user_type'},
            },

2.在前端初始化把choice元组设置成全局变量,因为很多地方都可以用到.

    function initglobal(global_dict) {
//       设置全局变量;
//       'global_dict':{
//               'user_choice':models.UserInfo.user_choice,}
//       拿到的是字符串,想要user_choice=models.UserInfo.user_choice
//        等于
//      window['user_choice']=models.UserInfo.user_choice
        $.each(global_dict,function (k,v) {
            window[k] =v
        })
    }

3.在全局变量里获取@@的值

放在第三个循环里.
两个@@是if
一个@是else if
if (values.substring(0,2) =='@@'){
                            // {#有两个@代表取choice里的值
//                               user_choice=(
//                                   (1,'普通用户'),
//                                   (2,'VIP'),
//                               )
                                var global_name = values.substring(2,values.length);
                                var current_id = data_values[config_values.q];
                                var ret = GetTextFromGlobalById(global_name,current_id);
                                new_kwargs[key] =ret
                            }

function GetTextFromGlobalById(global_name,current_id) {
        var ret = null;
        $.each(window[global_name],function (k,item) {
//           console.log(item,current_id)
//               [1, "普通用户"]      1
//               [2, "VIP"]          1
//               [1, "普通用户"]      1
//               [2, "VIP"]          1
//          如果 item[0] == current_i 返回内容 return跳出循环
            if (item[0] == current_id){
                ret = item[1];
                return
            }
        });
        return ret
    }

6.设置attr(标签的属性)

给标签设置attr属性.

可编辑,不可编辑,编辑类型.

设置attr在第二层循环的时候加一层.和并列第三层

//                         循环attrs,将属性和值赋值给标签.
//                      'attrs': {'edit': 'true', 'edit-type': 'select'},
                    $.each(config_values.attrs,function (attrs_key,attrs_values) {
                            if (attrs_values[0]=='@'){
                                td.attr(attrs_key,data_values[attrs_values.substring(1,attrs_values.length)])
                            }
                            else{
                                td.attr(attrs_key,attrs_values)
                                }
                        });

在这里设置attr的时候可以通过@的符号来获取数据库的值.

跨表的时候q用__来跨表''q'':'FK__'

7.简单的使用

1.选项:

{
    'q': None,
    'title': '选项',
    'display': 1,
    'text': {
        'content':'<input type="checkbox"/>'
    },
    'attrs': {},

},

2.不显示的
{
    'q': 'id',
    'title': 'ID',
    'display': 0,
    'text':None,
    'attrs': {},

},
3.显示且可以编辑的:
{
    'q': 'username',
    'title': '姓名',
    'display': 1,
    'text':{'content':'{username}',
            'kwargs':{'username':'@username'}},
    'attrs': {'edit-enalbe':'true','edit-type':'input',
              'name':'username','origin':'@username'},

},
4.跨表....显示不可编辑的:
{
    'q': 'user2blog__surfix',
    'title': '博客地址',
    'display': 1,
    'text': {'content': '{n}',
             'kwargs': {'n': '@user2blog__surfix'}},
    'attrs': {'edit-enalbe':'fault'},

},
5.choice类型:
{
    'q': 'user_type',
    'title': '用户类型',
    'display': 1,
    'text': {'content': '{n}',
             #               @@ 后面的数据是要选择的元组
             #                和一个@的区分开
             'kwargs': {'n': '@@user_choice'}},
    'attrs': {'edit-enalbe':'true', 'edit-type':'select'
               ,'global-name':'user_choice','origin':'@user_type',
              'name':'user_type'},
},
6.操作类型.
{
    'q': None,
    'title': '操作',
    'display': 1,
    'text': {'content': '<a href="/index-{nid}">{m}</a>',
             'kwargs': {'nid': '@id',"m":'查看详细'}},
    'attrs': {},
},

https://www.cnblogs.com/chenxuming/p/9253361.html

CURD

  CURD是一个数据库技术中的缩写词,一般的项目开发的各种参数的基本功能都是CURD。作用是用于处理数据的基本原子操作。

  它代表创建(Create)、更新(Update)、读取(Retrieve)和删除(Delete)操作。

核心

  1.前端页面通过ajax方式请求后台数据库数据

  2.后台 配置文件 指定字段去数据库取相应的字段返回给前端ajax

  3.前端通过jquery 实现前端页面数据修改,将修改数据再次通过ajax返回给后台

具体实现

  前端ajax获取数据

    在js自执行函数中,写入代码,定义全局变量 requestURL,方便后面传入新的ajax 提交路径,以ajax以get方式去后台获取数据. 获取到后台 result 数据,将其传递到 对应函数执行

requestURL = null;

function init(pager) {
                $.ajax(
                    {
                        url:requestURL,
                        data:{'pager':pager},
                        type:'GET',
                        dataType:'JSON',
                        success:function (result) {
                            initchoice(result.choice_dict);
                            initheader(result.table_config);
                            initbody(result.table_config,result.info)

                        }
                    }
                )
            };

  定义配置文件(整合 前端/数据库数据/显示样式)

    在后台 视图页面定义一个配置文件:

    数据结构为: 列表[字典方式]

      id , 作为数据库中的字段.

      title,前端显示的字段名

      display,是否在前端显示

      text,在前端可定义显示内容

      attrs,样式定义,提交name定义,修旧数值定义,文本类型定义(input?select?其他)

table_config = [
            {
                'id': None,
                'title': '选项',
                'display': 1,
                'text': {'key': "<input type='checkbox' />", 'val': {}},
                'attrs': {},
            },
            {
                'id':'id',
                'title':'ID',
                'display':1,
                'text':{'key':"{n}",'val':{'n':'@id'}},
                'attrs':{},
            },
            {
                'id': 'title',
                'title': '标题',
                'display': 1,
                'text': {'key': "{n}", 'val': {'n': '@title'}},
                'attrs': {'name':'title',"origin":'@title','edit-enable':'true','edit-type':'input'},
            },
            {
                'id': 'status',
                'title': '状态',
                'display': 1,
                'text': {'key': "{n}", 'val': {'n': '@@device_type_choice'}},
                'attrs': {'name':'status',"origin":'@status','edit-enable':'true','edit-type':'select',"global-name":'device_type_choice'},
            },
            {
                'id': 'pro_id',
                'title': '处理人',
                'display': 1,
                'text': {'key': "{n}", 'val': {'n': '@@device_type_userinfo'}},
                'attrs': {'name':'pro_id',"origin":'@pro_id','edit-enable':'true','edit-type':'select',"global-name":'device_type_userinfo'},
            },
            {
                'id': 'sol',
                'title': '处理详情',
                'display': 1,
                'text': {'key': "{n}", 'val': {'n': '@sol'}},
                'attrs': {'name': 'sol', "origin": '@sol', 'edit-enable': 'true', 'edit-type': 'input'},
            },
            {
                'id': None,
                'title': '操作',
                'display': 1,
                'text': {'key': "<a href='#'>添加</a>|<a href='#'>删除</a>", 'val': {}},
                'attrs': {},
            },
        ]

    数据库表(贴出来做参考的,上面只是截取了表中部分字段显示)

class Fault(models.Model):
    id = models.AutoField(primary_key=True,null=False)
    title = models.CharField(max_length=20,verbose_name="报障标题")
    detail = models.TextField(verbose_name="报障详细信息")
    user_id = models.ForeignKey('Userinfo',
                                to_field='uid',
                                on_delete=models.CASCADE,
                                verbose_name="报障人",
                                related_name='u')
    choice = (
        (1, '待处理'),
        (2, '处理中'),
        (3, '已处理'),
    )
    status = models.IntegerField(choices=choice,verbose_name='处理状态',default=1)
    ctime = models.DateTimeField(null=False, auto_now_add=True, verbose_name='创建时间')
    pro = models.ForeignKey('Userinfo',
                            to_field='uid',
                            on_delete=models.CASCADE,
                            verbose_name="处理人",
                            null=True,
                            blank=True,
                            related_name='p',
                            )
    sol = models.TextField(null=True,verbose_name="解决方案")
    ptime = models.DateTimeField(null=True)

  获取冲数据库中获取指定字段数据  

    视图将配置文件中id字段循环出来加入到zd列表列表中,然后去数据库中取指定字段的数据,将其整合到result字典中,转为json字符串传递到 前端ajax 回到函数中.

def ajaxdate(request):
    import json
    if request.method == "GET":
        table_config = [...]
        zd = []
        for i in table_config:
            if i['id']:
                zd.append(i['id'])
        info = models.Fault.objects.values(*zd).all()
        choice = models.Fault.choice
        userinfo = models.Userinfo.objects.all().values_list('uid','uname')

        result = {
            'table_config':table_config,
            'info':list(info),
            'choice_dict':{'device_type_choice':choice,'device_type_userinfo':list(userinfo)},
        }

        return HttpResponse(json.dumps(result))

ajax回到执行函数(显示表头、显示主体数据、添加html全局变量)

  这样就将后台的表头,数据都显示到前端

           // {#列表表头显示部分#}
            function initheader(table_config) {
                var tr = document.createElement('tr');
                $.each(table_config,function (k,item) {
                    var th = document.createElement('th');
                    if (item.display){
                        th.innerHTML = item.title;
                        $(tr).append(th);
                    }
                });
                $('#table_th').empty();
                $('#table_th').append(tr);
            }

            // {#列表数据显示部分#}
            function initbody(table_config,info){
                $('#table_td').empty();
                $.each(info,function (i,j) {
                    var tr = document.createElement('tr');
                    tr.setAttribute('j-id',j['id']);
                    var dictinfo = {};
                    $.each(table_config,function (x,y) {
                         if (y.display) {
                             $.each(y.text.val,function (k,v) {
                                 if(v.substring(0,2) ==='@@'){
                                    var gname = v.substring(2,v.length);
                                    var gid = j[y.id];
                                    var t = test(gname,gid);
                                    dictinfo[k] =t;

                                 }else if (v[0] ==='@'){
                                     dictinfo[k] = j[v.substring(1,v.length)];
                                 }else {
                                     dictinfo[k] = v;}
                             });
                         var td = document.createElement('td');
                         var ss = y.text.key.format(dictinfo);
                         td.innerHTML = ss;

                         $.each(y.attrs,function (q,t) {
                             if(t[0] === '@'){
                                 td.setAttribute(q,j[t.substring(1,t.length)]);
                             }else {
                                 td.setAttribute(q,t)
                             }
                         });

                         $(tr).append(td);}
                    });
                    $('#table_td').append(tr)})}

            // {#choice数据类型,定义全局变量#}
            function initchoice(choice_dict) {
                $.each(choice_dict,function (i,j) {
                    window[i]=j;
                })
            }

            // {#将以数据id去choice全局变量取对应的 中文显示信息#}
            function test(gname,gid) {
                var ret = null;
                $.each(window[gname], function (k, item) {
                    if (item[0] === gid) {
                        ret = item[1];
                        return
                    }
                });
                return ret;
            }

  前端html 添加操作按钮

    <h1>用户信息</h1>
    <div class="btn-group" role="group" aria-label="...">
      <button id="bindall" type="button" class="btn btn-default">全选</button>
      <button id="bindfx" type="button" class="btn btn-default">反选</button>
      <button id="unbindall" type="button" class="btn btn-default">取消</button>
      <button id="bindbj" type="button" class="btn btn-default">进入编辑模式</button>
      <button type="button" class="btn btn-default">批量删除</button>
      <button id='save' type="button" class="btn btn-default">保存</button>
    </div>
        <table class="table table-bordered table-hover">
            <thead id="table_th"></thead>
            <tbody id="table_td"></tbody>
        </table>

  自定义format字符串方法

// {#自定义的 字符format的方法#}
            String.prototype.format = function(kwargs){
              var ret = this.replace(/\{(\w+)\}/g,function (k,m) {
                  return kwargs[m]
              });
              return ret
            };

  用jquery绑定事件

            function bindsave(){
                $('#save').click(function () {
                    var postlist=[];
                    $('#table_td').find('tr[has-edit="true"]').each(function () {
                        var temp = {};
                        var id = $(this).attr('j-id');
                        temp['id'] = id;
                        $(this).children('[edit-enable="true"]').each(function () {
                            var name = $(this).attr('name');
                            var origin = $(this).attr('origin');
                            var newval = $(this).attr('new-val');
                            if(origin != newval){
                                temp[name] = newval;
                            };
                        })
                        postlist.push(temp);
                        $.ajax({
                            url:requestURL,
                            type:'POST',
                            data:{'post_list':JSON.stringify(postlist)},
                            dataType:'Json',
                            success:function (arg) {
                                if(arg.status){
                                    init(1);
                                }else {
                                    alter(arg);
                                }
                            }

                        })

                    })

                })
            }
            function bindM() {
                $('#bindbj').click(function () {
                    var ed = $(this).hasClass('btn-warning');
                    if(ed){
                         $(this).removeClass('btn-warning');
                         $(this).text("进入编辑模式");
                         $('#table_td').find(':checked').each(function () {
                             var $cur = $(this).parent().parent();
                             bjhangout($cur);
                         })
                    }else {
                        $(this).addClass('btn-warning');
                        $(this).text("退出编辑模式");
                        $('#table_td').find(':checked').each(function () {
                             var $cur = $(this).parent().parent();
                             bjhang($cur);
                         })
                    }
                })
            }
            function bindC() {
                // {#$('#table_td').find(':checkbox').click()
                // 这种方式新增数据无法被选中#}
                $('#table_td').on('click',':checkbox',function () {
                    if($('#bindbj').hasClass('btn-warning')){
                        var ck = $(this).prop('checked');
                        var $cur = $(this).parent().parent();
                        if(ck){
                            // {#console.log("进入编辑模式");#}
                            bjhang($cur)
                        }else{
                            // {#console.log("退出编辑模式");#}
                            bjhangout($cur)
                        }
                    }
                })
            }
            function bjhang(cur) {
                cur.attr('has-edit','true');
                cur.children().each(function () {
                    cur.addClass('success');
                    var editenable = $(this).attr('edit-enable');
                    var editetype = $(this).attr('edit-type');
                    if (editenable === 'true'){
                        if(editetype === 'select'){
                            var globalname = $(this).attr("global-name");
                            var origin = $(this).attr("origin");
                            var sel = document.createElement('select');
                            sel.className = "form-control";
                            $.each(window[globalname],function (k,v) {
                                var op = document.createElement('option');
                                op.innerHTML = v[1];
                                op.setAttribute('value',v[0]);
                                $(sel).append(op)
                            });
                            $(sel).val(origin);
                            $(this).html(sel);

                        }else if(editetype === 'input'){
                            var intext = $(this).text();
                            var tag = document.createElement('input');
                            tag.className = "form-control";
                            tag.value = intext;
                            $(this).html(tag)
                        }
                    }})}
            function bjhangout(cur) {
                cur.removeClass('success');
                cur.children().each(function () {
                    var editenable = $(this).attr('edit-enable');
                    if (editenable === 'true'){
                        var editetype = $(this).attr('edit-type');
                        if(editetype === 'select'){
                                var $select = $(this).children().first() ;
                                var newid = $select.val();
                                var newtext = $select[0].selectedOptions[0].innerHTML;
                                $(this).html(newtext);
                                $(this).attr('new-val',newid)

                        }else if(editetype === 'input'){
                            var $input2 = $(this).children().first() ;
                            var tag2 = $input2.val();
                            $(this).html(tag2);
                             $(this).attr('new-val',tag2)

                        }}})}
            function bindall() {
                $('#bindall').click(function () {
                    $('#table_td').find(':checkbox').each(function () {
                        if($('#bindbj').hasClass('btn-warning')){
                            if($(this).prop('checked')){

                            }else {
                                $(this).prop('checked',true);
                                var $cur = $(this).parent().parent();
                                bjhang($cur)
                            }
                        }else {
                            $(this).prop('checked',true);
                        };
                    })
                })
            }
            function unbindall() {
                  $('#unbindall').click(function () {
                      $('#table_td').find(':checked').each(function () {
                            if($('#bindbj').hasClass('btn-warning')){
                                $(this).prop('checked',false);
                                var $cur = $(this).parent().parent();
                                bjhangout($cur);
                            }else {
                                $(this).prop('checked',false);
                            }
                      })
                  })
            }
            function bindfx() {
                $('#bindfx').click(function () {
                      $('#table_td').find(':checkbox').each(function () {
                            if($('#bindbj').hasClass('btn-warning')){
                                var $cur = $(this).parent().parent();
                                if ($(this).prop('checked')){
                                    $(this).prop('checked',false);
                                    bjhangout($cur);
                                }else {
                                    $(this).prop('checked',true);
                                    bjhang($cur);
                                }
                            }else {
                                if ($(this).prop('checked')){
                                    $(this).prop('checked',false);
                                }else {
                                    $(this).prop('checked',true);
                                }
                            }
                      })
                  })
            }

完整代码

html - 模板

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
{#    <title>Title</title>#}
    <!--单独子版的title-->
    <title>{% block title %}{% endblock %}</title>

    <!--单独子版的css-->
    {% block css %}{% endblock %}
        <style>
        .item{

        }
         .title{
             font-size: 20px;
         }
         .content{
             margin-left: 30px;
         }
        .content a{
            display: block;
        }
    </style>
    <link type="text/css" rel="stylesheet" href="/static/css/muban-css.css">
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/font-awesome-4.7.0/css/font-awesome.min.css">
</head>
<body>

{#头部 start#}
    <div class="pg-header">
        <!--共享的-->
        {#头部菜单导航条#}
        <div class="logo left">Anec后台管理</div>
        <div class="hl-menu left">
            <a href="#" class="item">菜单一</a>
            <div class="item-set">
                <a href="#" class="item">菜单二</a>
                <div class="sets hide">
                    <a href="#" >菜单二1</a>
                    <a href="#" >菜单二2</a>
                    <a href="#" >菜单二3</a>
                </div>
            </div>
            <div class="item-set">
                <a href="#" class="item">菜单三</a>
                <div class="sets hide">
                    <a href="#" >菜单三1</a>
                    <a href="#" >菜单三2</a>
                    <a href="#" >菜单三3</a>
                </div>
            </div>
            <div class="item-set">
                <a href="#" class="item">菜单四</a>
                <div class="sets hide">
                    <a href="#" >菜单四1</a>
                    <a href="#" >菜单四2</a>
                    <a href="#" >菜单四3</a>
                </div>
            </div>

        </div>
        {#个人消息通知栏#}
        <div class="hr-menu right">
             <a href="#" class="item"><i class="fa fa-envelope" aria-hidden="true"></i>消息</a>
             <a href="#" class="item"><i class="fa fa-phone-square" aria-hidden="true"></i>通知</a>
             <a href="#" class="item"><i class="fa fa-server" aria-hidden="true"></i>任务</a>
            <div class="avatar">
                <a href="#" class="item">
{#                    <img src="111.jpg" >#}
                    <i class="fa fa-user-circle-o fa-2x" aria-hidden="true"></i>
                </a>
                <div class="sets hide">
                    <a href="#" >菜单1</a>
                    <a href="#" >菜单2</a>
                    <a href="#" >菜单3</a>
                </div>
            </div>

        </div>
    </div>
{#头部 end#}

{#div_body start #}
    <div class="pg-body">
    {#body-菜单栏 start#}
        <div class="menus">
            <!--共享的-->
            <div class="item">
                <div class="item-title"><a>功能1</a></div>
                <div class="item-content ">
                    <a href="/clbzd-ck">报障单</a>
                    <a>功能1-2</a>
                    <a>功能1-3</a>
                </div>
            </div>
            {% block menu %}{% endblock %}
        </div>
    {#body-菜单栏 end#}

    {#body-内容栏 start#}
        <div class="countents">
            <!--单独显示的-->
            <div class="countents-top">

            </div>
            <div class="countent">
                {% block countent %}{% endblock %}
            </div>
        </div>
    {#body-内容栏 end#}
    </div>
{#div_body end #}

{#div foot start#}
    <div class="pg-foot">
        <!--共享的-->
    </div>
{#div foot end#}

    <!--单独子版js-->
    {% block js %}{% endblock %}

</body>
</html>

html 代码

{% extends "htmb.html" %}

{% block css %}
    <link rel="stylesheet" href="/static/bootstrap/bootstrap-3.3.7-dist/css/bootstrap.min.css">
{% endblock %}

{% block js %}
    <script src="/static/js/jquery-1.7.1.min.js"></script>
    <script src="/static/js/cmdbzj.js"></script>
    <script>
        $(function () {
            $.NB( '/ajax-date.html')
        })

    </script>
{% endblock %}

{% block title %}
{% endblock %}

{% block menu %}
{% endblock %}

{% block countent %}
    <h1>用户信息</h1>
    <div class="btn-group" role="group" aria-label="...">
      <button id="bindall" type="button" class="btn btn-default">全选</button>
      <button id="bindfx" type="button" class="btn btn-default">反选</button>
      <button id="unbindall" type="button" class="btn btn-default">取消</button>
      <button id="bindbj" type="button" class="btn btn-default">进入编辑模式</button>
      <button type="button" class="btn btn-default">批量删除</button>
      <button id='save' type="button" class="btn btn-default">保存</button>
    </div>
        <table class="table table-bordered table-hover">
            <thead id="table_th"></thead>
            <tbody id="table_td"></tbody>
        </table>
{% endblock %}

封装的JS代码

// 自执行函数
(function () {
            requestURL = null;

            // {#自定义的 字符format的方法#}
            String.prototype.format = function(kwargs){
              var ret = this.replace(/\{(\w+)\}/g,function (k,m) {
                  return kwargs[m]
              });
              return ret
            };

            function bindsave(){
                $('#save').click(function () {
                    var postlist=[];
                    $('#table_td').find('tr[has-edit="true"]').each(function () {
                        var temp = {};
                        var id = $(this).attr('j-id');
                        temp['id'] = id;
                        $(this).children('[edit-enable="true"]').each(function () {
                            var name = $(this).attr('name');
                            var origin = $(this).attr('origin');
                            var newval = $(this).attr('new-val');
                            if(origin != newval){
                                temp[name] = newval;
                            };
                        })
                        postlist.push(temp);
                        $.ajax({
                            url:requestURL,
                            type:'POST',
                            data:{'post_list':JSON.stringify(postlist)},
                            dataType:'Json',
                            success:function (arg) {
                                if(arg.status){
                                    init(1);
                                }else {
                                    alter(arg);
                                }
                            }

                        })

                    })

                })
            }
            function bindM() {
                $('#bindbj').click(function () {
                    var ed = $(this).hasClass('btn-warning');
                    if(ed){
                         $(this).removeClass('btn-warning');
                         $(this).text("进入编辑模式");
                         $('#table_td').find(':checked').each(function () {
                             var $cur = $(this).parent().parent();
                             bjhangout($cur);
                         })
                    }else {
                        $(this).addClass('btn-warning');
                        $(this).text("退出编辑模式");
                        $('#table_td').find(':checked').each(function () {
                             var $cur = $(this).parent().parent();
                             bjhang($cur);
                         })
                    }
                })
            }
            function bindC() {
                // {#$('#table_td').find(':checkbox').click()
                // 这种方式新增数据无法被选中#}
                $('#table_td').on('click',':checkbox',function () {
                    if($('#bindbj').hasClass('btn-warning')){
                        var ck = $(this).prop('checked');
                        var $cur = $(this).parent().parent();
                        if(ck){
                            // {#console.log("进入编辑模式");#}
                            bjhang($cur)
                        }else{
                            // {#console.log("退出编辑模式");#}
                            bjhangout($cur)
                        }
                    }
                })
            }
            function bjhang(cur) {
                cur.attr('has-edit','true');
                cur.children().each(function () {
                    cur.addClass('success');
                    var editenable = $(this).attr('edit-enable');
                    var editetype = $(this).attr('edit-type');
                    if (editenable === 'true'){
                        if(editetype === 'select'){
                            var globalname = $(this).attr("global-name");
                            var origin = $(this).attr("origin");
                            var sel = document.createElement('select');
                            sel.className = "form-control";
                            $.each(window[globalname],function (k,v) {
                                var op = document.createElement('option');
                                op.innerHTML = v[1];
                                op.setAttribute('value',v[0]);
                                $(sel).append(op)
                            });
                            $(sel).val(origin);
                            $(this).html(sel);

                        }else if(editetype === 'input'){
                            var intext = $(this).text();
                            var tag = document.createElement('input');
                            tag.className = "form-control";
                            tag.value = intext;
                            $(this).html(tag)
                        }
                    }})}
            function bjhangout(cur) {
                cur.removeClass('success');
                cur.children().each(function () {
                    var editenable = $(this).attr('edit-enable');
                    if (editenable === 'true'){
                        var editetype = $(this).attr('edit-type');
                        if(editetype === 'select'){
                                var $select = $(this).children().first() ;
                                var newid = $select.val();
                                var newtext = $select[0].selectedOptions[0].innerHTML;
                                $(this).html(newtext);
                                $(this).attr('new-val',newid)

                        }else if(editetype === 'input'){
                            var $input2 = $(this).children().first() ;
                            var tag2 = $input2.val();
                            $(this).html(tag2);
                             $(this).attr('new-val',tag2)

                        }}})}
            function bindall() {
                $('#bindall').click(function () {
                    $('#table_td').find(':checkbox').each(function () {
                        if($('#bindbj').hasClass('btn-warning')){
                            if($(this).prop('checked')){

                            }else {
                                $(this).prop('checked',true);
                                var $cur = $(this).parent().parent();
                                bjhang($cur)
                            }
                        }else {
                            $(this).prop('checked',true);
                        };
                    })
                })
            }
            function unbindall() {
                  $('#unbindall').click(function () {
                      $('#table_td').find(':checked').each(function () {
                            if($('#bindbj').hasClass('btn-warning')){
                                $(this).prop('checked',false);
                                var $cur = $(this).parent().parent();
                                bjhangout($cur);
                            }else {
                                $(this).prop('checked',false);
                            }
                      })
                  })
            }
            function bindfx() {
                $('#bindfx').click(function () {
                      $('#table_td').find(':checkbox').each(function () {
                            if($('#bindbj').hasClass('btn-warning')){
                                var $cur = $(this).parent().parent();
                                if ($(this).prop('checked')){
                                    $(this).prop('checked',false);
                                    bjhangout($cur);
                                }else {
                                    $(this).prop('checked',true);
                                    bjhang($cur);
                                }
                            }else {
                                if ($(this).prop('checked')){
                                    $(this).prop('checked',false);
                                }else {
                                    $(this).prop('checked',true);
                                }
                            }
                      })
                  })
            }

            // {#用ajax get方式获取后台的json数据#}
            function init(pager) {
                $.ajax(
                    {
                        url:requestURL,
                        data:{'pager':pager},
                        type:'GET',
                        dataType:'JSON',
                        success:function (result) {
                            initchoice(result.choice_dict);
                            initheader(result.table_config);
                            initbody(result.table_config,result.info)
                        }
                    }
                )
            };

            // {#列表表头显示部分#}
            function initheader(table_config) {
                var tr = document.createElement('tr');
                $.each(table_config,function (k,item) {
                    var th = document.createElement('th');
                    if (item.display){
                        th.innerHTML = item.title;
                        $(tr).append(th);
                    }
                });
                $('#table_th').empty();
                $('#table_th').append(tr);
            }

            // {#列表数据显示部分#}
            function initbody(table_config,info){
                $('#table_td').empty();
                $.each(info,function (i,j) {
                    var tr = document.createElement('tr');
                    tr.setAttribute('j-id',j['id']);
                    var dictinfo = {};
                    $.each(table_config,function (x,y) {
                         if (y.display) {
                             $.each(y.text.val,function (k,v) {
                                 if(v.substring(0,2) ==='@@'){
                                    var gname = v.substring(2,v.length);
                                    var gid = j[y.id];
                                    var t = test(gname,gid);
                                    dictinfo[k] =t;

                                 }else if (v[0] ==='@'){
                                     dictinfo[k] = j[v.substring(1,v.length)];
                                 }else {
                                     dictinfo[k] = v;}
                             });
                         var td = document.createElement('td');
                         var ss = y.text.key.format(dictinfo);
                         td.innerHTML = ss;

                         $.each(y.attrs,function (q,t) {
                             if(t[0] === '@'){
                                 td.setAttribute(q,j[t.substring(1,t.length)]);
                             }else {
                                 td.setAttribute(q,t)
                             }
                         });

                         $(tr).append(td);}
                    });
                    $('#table_td').append(tr)})}

            // {#choice数据类型,定义全局变量#}
            function initchoice(choice_dict) {
                $.each(choice_dict,function (i,j) {
                    window[i]=j;
                })
            }

            // {#将以数据id去choice全局变量取对应的 中文显示信息#}
            function test(gname,gid) {
                var ret = null;
                $.each(window[gname], function (k, item) {
                    if (item[0] === gid) {
                        ret = item[1];
                        return
                    }
                });
                return ret;
            }

            jQuery.extend({
                'NB':function (url) {
                    requestURL = url;
                    init();
                    bindM();
                    bindC();
                    bindall();
                    unbindall();
                    bindfx();
                    bindsave();
                },
                'changepager':function (num) {
                    init(num);
                }
            })
})();

   views完整代码

def ajaxdate(request):
    import json
    if request.method == "GET":
        table_config = [
            {
                'id': None,
                'title': '选项',
                'display': 1,
                'text': {'key': "<input type='checkbox' />", 'val': {}},
                'attrs': {},
            },
            {
                'id':'id',
                'title':'ID',
                'display':1,
                'text':{'key':"{n}",'val':{'n':'@id'}},
                'attrs':{},
            },
            {
                'id': 'title',
                'title': '标题',
                'display': 1,
                'text': {'key': "{n}", 'val': {'n': '@title'}},
                'attrs': {'name':'title',"origin":'@title','edit-enable':'true','edit-type':'input'},
            },
            {
                'id': 'status',
                'title': '状态',
                'display': 1,
                'text': {'key': "{n}", 'val': {'n': '@@device_type_choice'}},
                'attrs': {'name':'status',"origin":'@status','edit-enable':'true','edit-type':'select',"global-name":'device_type_choice'},
            },
            {
                'id': 'pro_id',
                'title': '处理人',
                'display': 1,
                'text': {'key': "{n}", 'val': {'n': '@@device_type_userinfo'}},
                'attrs': {'name':'pro_id',"origin":'@pro_id','edit-enable':'true','edit-type':'select',"global-name":'device_type_userinfo'},
            },
            {
                'id': 'sol',
                'title': '处理详情',
                'display': 1,
                'text': {'key': "{n}", 'val': {'n': '@sol'}},
                'attrs': {'name': 'sol', "origin": '@sol', 'edit-enable': 'true', 'edit-type': 'input'},
            },
            {
                'id': None,
                'title': '操作',
                'display': 1,
                'text': {'key': "<a href='#'>添加</a>|<a href='#'>删除</a>", 'val': {}},
                'attrs': {},
            },
        ]
        zd = []
        for i in table_config:
            if i['id']:
                zd.append(i['id'])
        info = models.Fault.objects.values(*zd).all()
        choice = models.Fault.choice
        userinfo = models.Userinfo.objects.all().values_list('uid','uname')

        result = {
            'table_config':table_config,
            'info':list(info),
            'choice_dict':{'device_type_choice':choice,'device_type_userinfo':list(userinfo)},
        }
        return HttpResponse(json.dumps(result))

    elif request.method == "POST":
        content = json.loads(request.POST['post_list'])
        if content:
            for i in content:
                models.Fault.objects.filter(id=i['id']).update_or_create(i)

        ret = {'status':'OK'}
        return HttpResponse('OK')

https://www.cnblogs.com/Anec/p/10093410.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券