当前位置:   article > 正文

Django之CURD插件_django cms curd

django cms curd

什么是CURD?

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

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

1.配置文件

配置文件需要放上面?

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

    'title':表单的head名

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

    text:{content:.....

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

2.数据库内容

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

4.分页

  1. msg={
  2. 'config':config,
  3. 'data_list':list(data_list),
  4. 'global_dict':{
  5. 'user_choice':models.UserInfo.user_choice,
  6. },
  7. 'page_str':page_str,
  8. }
  9. config = [
  10. {
  11. 'q': None,
  12. 'title': '选项',
  13. 'display': 1,
  14. 'text': {
  15. 'content':'<input type="checkbox"/>'
  16. },
  17. 'attrs': {},
  18. },
  19. {
  20. 'q': 'id',
  21. 'title': 'ID',
  22. 'display': 0,
  23. 'text':None,
  24. 'attrs': {},
  25. },
  26. {
  27. 'q': 'username',
  28. 'title': '姓名',
  29. 'display': 1,
  30. 'text':{'content':'{username}',
  31. 'kwargs':{'username':'@username'}},
  32. 'attrs': {'edit-enalbe':'true','edit-type':'input',
  33. 'name':'username','origin':'@username'},
  34. },
  35. {
  36. 'q': 'user_type',
  37. 'title': '用户类型',
  38. 'display': 1,
  39. 'text': {'content': '{n}',
  40. # @@ 后面的数据是要选择的元组
  41. # 和一个@的区分开
  42. 'kwargs': {'n': '@@user_choice'}},
  43. 'attrs': {'edit-enalbe':'true', 'edit-type':'select'
  44. ,'global-name':'user_choice','origin':'@user_type',
  45. 'name':'user_type'},
  46. },
  47. {
  48. 'q': 'nickname',
  49. 'title': '昵称',
  50. 'display': 1,
  51. 'text': {'content': '{nick}',
  52. 'kwargs': {'nick': '@nickname'}},
  53. 'attrs': {'edit-enalbe': 'true', 'edit-type': 'input',
  54. 'name':'nickname','origin':'@nickname'},
  55. },
  56. {
  57. 'q': 'user2blog__surfix',
  58. 'title': '博客地址',
  59. 'display': 1,
  60. 'text': {'content': '{n}',
  61. 'kwargs': {'n': '@user2blog__surfix'}},
  62. 'attrs': {'edit-enalbe':'fault'},
  63. },
  64. {
  65. 'q': None,
  66. 'title': '操作',
  67. 'display': 1,
  68. 'text': {'content': '<a href="/index-{nid}">{m}</a>',
  69. 'kwargs': {'nid': '@id',"m":'查看详细'}},
  70. 'attrs': {},
  71. },
  72. ]

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

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

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

操作没有数据则q为None

2.初始化table的head

  1. function initHead(config) {
  2. $('#talbe_th').empty();
  3. var tr = $('<tr></tr>');
  4. $.each(config,function (k,v) {
  5. if (v.display){
  6. var th=$('<th></th>');
  7. th.html(v.title);
  8. tr.append(th)
  9. }
  10. });

3.{}的格式化

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

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

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

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

4.一个@

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

如何取?

**思路**

嵌套三层循环

1.第一层:

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

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

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

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

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

  1. function initBody(config,data_list) {
  2. $("#table_tb").empty();
  3. // 第一层
  4. $.each(data_list,function (data_key,data_values) {
  5. var tr = $('<tr></tr>');
  6. tr.attr('row-id',data_values['id']);
  7. // 第二层,循环配置文件的config列表
  8. // 一个字典里: {
  9. // 'q': 'username',
  10. // 'title': '姓名',
  11. // 'display': 1,
  12. // 'text':{'content':'{username}-{id}',
  13. // 'kwargs':{'username':'@username','id':'@id'}
  14. $.each(config,function (config_key,config_values) {
  15. if (config_values.display){
  16. var new_kwargs={};
  17. var td=$('<td></td>');
  18. // 第三层
  19. $.each(config_values.text.kwargs,function (key,values) {else if (values[0]=='@'){
  20. // 有一个@的代表去数据库的值
  21. new_kwargs[key] = data_values[values.substring(1,values.length)];
  22. }
  23. else{
  24. new_kwargs[key] = values
  25. }
  26. }
  27. );
  28. var temp = config_values.text.content.format(new_kwargs);
  29. td.html(temp);
  30. tr.append(td)
  31. }
  32. });
  33. $("#table_tb").append(tr);
  34. })
  35. }

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

5.两个@

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

**思路**

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

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

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

  1. function initglobal(global_dict) {
  2. // 设置全局变量;
  3. // 'global_dict':{
  4. // 'user_choice':models.UserInfo.user_choice,}
  5. // 拿到的是字符串,想要user_choice=models.UserInfo.user_choice
  6. // 等于
  7. // window['user_choice']=models.UserInfo.user_choice
  8. $.each(global_dict,function (k,v) {
  9. window[k] =v
  10. })
  11. }

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

  1. 放在第三个循环里.
  2. 两个@@是if
  3. 一个@是else if
  4. if (values.substring(0,2) =='@@'){
  5. // {#有两个@代表取choice里的值
  6. // user_choice=(
  7. // (1,'普通用户'),
  8. // (2,'VIP'),
  9. // )
  10. var global_name = values.substring(2,values.length);
  11. var current_id = data_values[config_values.q];
  12. var ret = GetTextFromGlobalById(global_name,current_id);
  13. new_kwargs[key] =ret
  14. }
  15. function GetTextFromGlobalById(global_name,current_id) {
  16. var ret = null;
  17. $.each(window[global_name],function (k,item) {
  18. // console.log(item,current_id)
  19. // [1, "普通用户"] 1
  20. // [2, "VIP"] 1
  21. // [1, "普通用户"] 1
  22. // [2, "VIP"] 1
  23. // 如果 item[0] == current_i 返回内容 return跳出循环
  24. if (item[0] == current_id){
  25. ret = item[1];
  26. return
  27. }
  28. });
  29. return ret
  30. }

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

给标签设置attr属性.

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

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

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

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

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

7.简单的使用

1.选项:

  1. {
  2. 'q': None,
  3. 'title': '选项',
  4. 'display': 1,
  5. 'text': {
  6. 'content':'<input type="checkbox"/>'
  7. },
  8. 'attrs': {},
  9. },
  10. 2.不显示的
  1. {
  2. 'q': 'id',
  3. 'title': 'ID',
  4. 'display': 0,
  5. 'text':None,
  6. 'attrs': {},
  7. },
  8. 3.显示且可以编辑的:
  1. {
  2. 'q': 'username',
  3. 'title': '姓名',
  4. 'display': 1,
  5. 'text':{'content':'{username}',
  6. 'kwargs':{'username':'@username'}},
  7. 'attrs': {'edit-enalbe':'true','edit-type':'input',
  8. 'name':'username','origin':'@username'},
  9. },
  10. 4.跨表....显示不可编辑的:
  1. {
  2. 'q': 'user2blog__surfix',
  3. 'title': '博客地址',
  4. 'display': 1,
  5. 'text': {'content': '{n}',
  6. 'kwargs': {'n': '@user2blog__surfix'}},
  7. 'attrs': {'edit-enalbe':'fault'},
  8. },
  9. 5.choice类型:
  1. {
  2. 'q': 'user_type',
  3. 'title': '用户类型',
  4. 'display': 1,
  5. 'text': {'content': '{n}',
  6. # @@ 后面的数据是要选择的元组
  7. # 和一个@的区分开
  8. 'kwargs': {'n': '@@user_choice'}},
  9. 'attrs': {'edit-enalbe':'true', 'edit-type':'select'
  10. ,'global-name':'user_choice','origin':'@user_type',
  11. 'name':'user_type'},
  12. },
  13. 6.操作类型.
  1. {
  2. 'q': None,
  3. 'title': '操作',
  4. 'display': 1,
  5. 'text': {'content': '<a href="/index-{nid}">{m}</a>',
  6. 'kwargs': {'nid': '@id',"m":'查看详细'}},
  7. 'attrs': {},
  8. },

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 数据,将其传递到 对应函数执行

复制代码

  1. requestURL = null;
  2. function init(pager) {
  3. $.ajax(
  4. {
  5. url:requestURL,
  6. data:{'pager':pager},
  7. type:'GET',
  8. dataType:'JSON',
  9. success:function (result) {
  10. initchoice(result.choice_dict);
  11. initheader(result.table_config);
  12. initbody(result.table_config,result.info)
  13. }
  14. }
  15. )
  16. };

复制代码

  

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

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

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

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

      title,前端显示的字段名

      display,是否在前端显示

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

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

复制代码

  1. table_config = [
  2. {
  3. 'id': None,
  4. 'title': '选项',
  5. 'display': 1,
  6. 'text': {'key': "<input type='checkbox' />", 'val': {}},
  7. 'attrs': {},
  8. },
  9. {
  10. 'id':'id',
  11. 'title':'ID',
  12. 'display':1,
  13. 'text':{'key':"{n}",'val':{'n':'@id'}},
  14. 'attrs':{},
  15. },
  16. {
  17. 'id': 'title',
  18. 'title': '标题',
  19. 'display': 1,
  20. 'text': {'key': "{n}", 'val': {'n': '@title'}},
  21. 'attrs': {'name':'title',"origin":'@title','edit-enable':'true','edit-type':'input'},
  22. },
  23. {
  24. 'id': 'status',
  25. 'title': '状态',
  26. 'display': 1,
  27. 'text': {'key': "{n}", 'val': {'n': '@@device_type_choice'}},
  28. 'attrs': {'name':'status',"origin":'@status','edit-enable':'true','edit-type':'select',"global-name":'device_type_choice'},
  29. },
  30. {
  31. 'id': 'pro_id',
  32. 'title': '处理人',
  33. 'display': 1,
  34. 'text': {'key': "{n}", 'val': {'n': '@@device_type_userinfo'}},
  35. 'attrs': {'name':'pro_id',"origin":'@pro_id','edit-enable':'true','edit-type':'select',"global-name":'device_type_userinfo'},
  36. },
  37. {
  38. 'id': 'sol',
  39. 'title': '处理详情',
  40. 'display': 1,
  41. 'text': {'key': "{n}", 'val': {'n': '@sol'}},
  42. 'attrs': {'name': 'sol', "origin": '@sol', 'edit-enable': 'true', 'edit-type': 'input'},
  43. },
  44. {
  45. 'id': None,
  46. 'title': '操作',
  47. 'display': 1,
  48. 'text': {'key': "<a href='#'>添加</a>|<a href='#'>删除</a>", 'val': {}},
  49. 'attrs': {},
  50. },
  51. ]

复制代码

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

复制代码

  1. class Fault(models.Model):
  2. id = models.AutoField(primary_key=True,null=False)
  3. title = models.CharField(max_length=20,verbose_name="报障标题")
  4. detail = models.TextField(verbose_name="报障详细信息")
  5. user_id = models.ForeignKey('Userinfo',
  6. to_field='uid',
  7. on_delete=models.CASCADE,
  8. verbose_name="报障人",
  9. related_name='u')
  10. choice = (
  11. (1, '待处理'),
  12. (2, '处理中'),
  13. (3, '已处理'),
  14. )
  15. status = models.IntegerField(choices=choice,verbose_name='处理状态',default=1)
  16. ctime = models.DateTimeField(null=False, auto_now_add=True, verbose_name='创建时间')
  17. pro = models.ForeignKey('Userinfo',
  18. to_field='uid',
  19. on_delete=models.CASCADE,
  20. verbose_name="处理人",
  21. null=True,
  22. blank=True,
  23. related_name='p',
  24. )
  25. sol = models.TextField(null=True,verbose_name="解决方案")
  26. ptime = models.DateTimeField(null=True)

复制代码

 

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

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

复制代码

  1. def ajaxdate(request):
  2. import json
  3. if request.method == "GET":
  4. table_config = [...]
  5. zd = []
  6. for i in table_config:
  7. if i['id']:
  8. zd.append(i['id'])
  9. info = models.Fault.objects.values(*zd).all()
  10. choice = models.Fault.choice
  11. userinfo = models.Userinfo.objects.all().values_list('uid','uname')
  12. result = {
  13. 'table_config':table_config,
  14. 'info':list(info),
  15. 'choice_dict':{'device_type_choice':choice,'device_type_userinfo':list(userinfo)},
  16. }
  17. return HttpResponse(json.dumps(result))

复制代码

 

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

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

复制代码

  1. // {#列表表头显示部分#}
  2. function initheader(table_config) {
  3. var tr = document.createElement('tr');
  4. $.each(table_config,function (k,item) {
  5. var th = document.createElement('th');
  6. if (item.display){
  7. th.innerHTML = item.title;
  8. $(tr).append(th);
  9. }
  10. });
  11. $('#table_th').empty();
  12. $('#table_th').append(tr);
  13. }
  14. // {#列表数据显示部分#}
  15. function initbody(table_config,info){
  16. $('#table_td').empty();
  17. $.each(info,function (i,j) {
  18. var tr = document.createElement('tr');
  19. tr.setAttribute('j-id',j['id']);
  20. var dictinfo = {};
  21. $.each(table_config,function (x,y) {
  22. if (y.display) {
  23. $.each(y.text.val,function (k,v) {
  24. if(v.substring(0,2) ==='@@'){
  25. var gname = v.substring(2,v.length);
  26. var gid = j[y.id];
  27. var t = test(gname,gid);
  28. dictinfo[k] =t;
  29. }else if (v[0] ==='@'){
  30. dictinfo[k] = j[v.substring(1,v.length)];
  31. }else {
  32. dictinfo[k] = v;}
  33. });
  34. var td = document.createElement('td');
  35. var ss = y.text.key.format(dictinfo);
  36. td.innerHTML = ss;
  37. $.each(y.attrs,function (q,t) {
  38. if(t[0] === '@'){
  39. td.setAttribute(q,j[t.substring(1,t.length)]);
  40. }else {
  41. td.setAttribute(q,t)
  42. }
  43. });
  44. $(tr).append(td);}
  45. });
  46. $('#table_td').append(tr)})}
  47. // {#choice数据类型,定义全局变量#}
  48. function initchoice(choice_dict) {
  49. $.each(choice_dict,function (i,j) {
  50. window[i]=j;
  51. })
  52. }
  53. // {#将以数据id去choice全局变量取对应的 中文显示信息#}
  54. function test(gname,gid) {
  55. var ret = null;
  56. $.each(window[gname], function (k, item) {
  57. if (item[0] === gid) {
  58. ret = item[1];
  59. return
  60. }
  61. });
  62. return ret;
  63. }

复制代码

 

  前端html 添加操作按钮

复制代码

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

复制代码

 

  自定义format字符串方法

复制代码

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

复制代码

 

  用jquery绑定事件

复制代码

  1. function bindsave(){
  2. $('#save').click(function () {
  3. var postlist=[];
  4. $('#table_td').find('tr[has-edit="true"]').each(function () {
  5. var temp = {};
  6. var id = $(this).attr('j-id');
  7. temp['id'] = id;
  8. $(this).children('[edit-enable="true"]').each(function () {
  9. var name = $(this).attr('name');
  10. var origin = $(this).attr('origin');
  11. var newval = $(this).attr('new-val');
  12. if(origin != newval){
  13. temp[name] = newval;
  14. };
  15. })
  16. postlist.push(temp);
  17. $.ajax({
  18. url:requestURL,
  19. type:'POST',
  20. data:{'post_list':JSON.stringify(postlist)},
  21. dataType:'Json',
  22. success:function (arg) {
  23. if(arg.status){
  24. init(1);
  25. }else {
  26. alter(arg);
  27. }
  28. }
  29. })
  30. })
  31. })
  32. }
  33. function bindM() {
  34. $('#bindbj').click(function () {
  35. var ed = $(this).hasClass('btn-warning');
  36. if(ed){
  37. $(this).removeClass('btn-warning');
  38. $(this).text("进入编辑模式");
  39. $('#table_td').find(':checked').each(function () {
  40. var $cur = $(this).parent().parent();
  41. bjhangout($cur);
  42. })
  43. }else {
  44. $(this).addClass('btn-warning');
  45. $(this).text("退出编辑模式");
  46. $('#table_td').find(':checked').each(function () {
  47. var $cur = $(this).parent().parent();
  48. bjhang($cur);
  49. })
  50. }
  51. })
  52. }
  53. function bindC() {
  54. // {#$('#table_td').find(':checkbox').click()
  55. // 这种方式新增数据无法被选中#}
  56. $('#table_td').on('click',':checkbox',function () {
  57. if($('#bindbj').hasClass('btn-warning')){
  58. var ck = $(this).prop('checked');
  59. var $cur = $(this).parent().parent();
  60. if(ck){
  61. // {#console.log("进入编辑模式");#}
  62. bjhang($cur)
  63. }else{
  64. // {#console.log("退出编辑模式");#}
  65. bjhangout($cur)
  66. }
  67. }
  68. })
  69. }
  70. function bjhang(cur) {
  71. cur.attr('has-edit','true');
  72. cur.children().each(function () {
  73. cur.addClass('success');
  74. var editenable = $(this).attr('edit-enable');
  75. var editetype = $(this).attr('edit-type');
  76. if (editenable === 'true'){
  77. if(editetype === 'select'){
  78. var globalname = $(this).attr("global-name");
  79. var origin = $(this).attr("origin");
  80. var sel = document.createElement('select');
  81. sel.className = "form-control";
  82. $.each(window[globalname],function (k,v) {
  83. var op = document.createElement('option');
  84. op.innerHTML = v[1];
  85. op.setAttribute('value',v[0]);
  86. $(sel).append(op)
  87. });
  88. $(sel).val(origin);
  89. $(this).html(sel);
  90. }else if(editetype === 'input'){
  91. var intext = $(this).text();
  92. var tag = document.createElement('input');
  93. tag.className = "form-control";
  94. tag.value = intext;
  95. $(this).html(tag)
  96. }
  97. }})}
  98. function bjhangout(cur) {
  99. cur.removeClass('success');
  100. cur.children().each(function () {
  101. var editenable = $(this).attr('edit-enable');
  102. if (editenable === 'true'){
  103. var editetype = $(this).attr('edit-type');
  104. if(editetype === 'select'){
  105. var $select = $(this).children().first() ;
  106. var newid = $select.val();
  107. var newtext = $select[0].selectedOptions[0].innerHTML;
  108. $(this).html(newtext);
  109. $(this).attr('new-val',newid)
  110. }else if(editetype === 'input'){
  111. var $input2 = $(this).children().first() ;
  112. var tag2 = $input2.val();
  113. $(this).html(tag2);
  114. $(this).attr('new-val',tag2)
  115. }}})}
  116. function bindall() {
  117. $('#bindall').click(function () {
  118. $('#table_td').find(':checkbox').each(function () {
  119. if($('#bindbj').hasClass('btn-warning')){
  120. if($(this).prop('checked')){
  121. }else {
  122. $(this).prop('checked',true);
  123. var $cur = $(this).parent().parent();
  124. bjhang($cur)
  125. }
  126. }else {
  127. $(this).prop('checked',true);
  128. };
  129. })
  130. })
  131. }
  132. function unbindall() {
  133. $('#unbindall').click(function () {
  134. $('#table_td').find(':checked').each(function () {
  135. if($('#bindbj').hasClass('btn-warning')){
  136. $(this).prop('checked',false);
  137. var $cur = $(this).parent().parent();
  138. bjhangout($cur);
  139. }else {
  140. $(this).prop('checked',false);
  141. }
  142. })
  143. })
  144. }
  145. function bindfx() {
  146. $('#bindfx').click(function () {
  147. $('#table_td').find(':checkbox').each(function () {
  148. if($('#bindbj').hasClass('btn-warning')){
  149. var $cur = $(this).parent().parent();
  150. if ($(this).prop('checked')){
  151. $(this).prop('checked',false);
  152. bjhangout($cur);
  153. }else {
  154. $(this).prop('checked',true);
  155. bjhang($cur);
  156. }
  157. }else {
  158. if ($(this).prop('checked')){
  159. $(this).prop('checked',false);
  160. }else {
  161. $(this).prop('checked',true);
  162. }
  163. }
  164. })
  165. })
  166. }

复制代码


 

完整代码

html - 模板

复制代码

  1. <!DOCTYPE html>
  2. <html >
  3. <head>
  4. <meta charset="UTF-8">
  5. {# <title>Title</title>#}
  6. <!--单独子版的title-->
  7. <title>{% block title %}{% endblock %}</title>
  8. <!--单独子版的css-->
  9. {% block css %}{% endblock %}
  10. <style>
  11. .item{
  12. }
  13. .title{
  14. font-size: 20px;
  15. }
  16. .content{
  17. margin-left: 30px;
  18. }
  19. .content a{
  20. display: block;
  21. }
  22. </style>
  23. <link type="text/css" rel="stylesheet" href="/static/css/muban-css.css">
  24. <link rel="stylesheet" href="/static/font-awesome-4.7.0/font-awesome-4.7.0/css/font-awesome.min.css">
  25. </head>
  26. <body>
  27. {#头部 start#}
  28. <div class="pg-header">
  29. <!--共享的-->
  30. {#头部菜单导航条#}
  31. <div class="logo left">Anec后台管理</div>
  32. <div class="hl-menu left">
  33. <a href="#" class="item">菜单一</a>
  34. <div class="item-set">
  35. <a href="#" class="item">菜单二</a>
  36. <div class="sets hide">
  37. <a href="#" >菜单二1</a>
  38. <a href="#" >菜单二2</a>
  39. <a href="#" >菜单二3</a>
  40. </div>
  41. </div>
  42. <div class="item-set">
  43. <a href="#" class="item">菜单三</a>
  44. <div class="sets hide">
  45. <a href="#" >菜单三1</a>
  46. <a href="#" >菜单三2</a>
  47. <a href="#" >菜单三3</a>
  48. </div>
  49. </div>
  50. <div class="item-set">
  51. <a href="#" class="item">菜单四</a>
  52. <div class="sets hide">
  53. <a href="#" >菜单四1</a>
  54. <a href="#" >菜单四2</a>
  55. <a href="#" >菜单四3</a>
  56. </div>
  57. </div>
  58. </div>
  59. {#个人消息通知栏#}
  60. <div class="hr-menu right">
  61. <a href="#" class="item"><i class="fa fa-envelope" aria-hidden="true"></i>消息</a>
  62. <a href="#" class="item"><i class="fa fa-phone-square" aria-hidden="true"></i>通知</a>
  63. <a href="#" class="item"><i class="fa fa-server" aria-hidden="true"></i>任务</a>
  64. <div class="avatar">
  65. <a href="#" class="item">
  66. {# <img src="111.jpg" >#}
  67. <i class="fa fa-user-circle-o fa-2x" aria-hidden="true"></i>
  68. </a>
  69. <div class="sets hide">
  70. <a href="#" >菜单1</a>
  71. <a href="#" >菜单2</a>
  72. <a href="#" >菜单3</a>
  73. </div>
  74. </div>
  75. </div>
  76. </div>
  77. {#头部 end#}
  78. {#div_body start #}
  79. <div class="pg-body">
  80. {#body-菜单栏 start#}
  81. <div class="menus">
  82. <!--共享的-->
  83. <div class="item">
  84. <div class="item-title"><a>功能1</a></div>
  85. <div class="item-content ">
  86. <a href="/clbzd-ck">报障单</a>
  87. <a>功能1-2</a>
  88. <a>功能1-3</a>
  89. </div>
  90. </div>
  91. {% block menu %}{% endblock %}
  92. </div>
  93. {#body-菜单栏 end#}
  94. {#body-内容栏 start#}
  95. <div class="countents">
  96. <!--单独显示的-->
  97. <div class="countents-top">
  98. </div>
  99. <div class="countent">
  100. {% block countent %}{% endblock %}
  101. </div>
  102. </div>
  103. {#body-内容栏 end#}
  104. </div>
  105. {#div_body end #}
  106. {#div foot start#}
  107. <div class="pg-foot">
  108. <!--共享的-->
  109. </div>
  110. {#div foot end#}
  111. <!--单独子版js-->
  112. {% block js %}{% endblock %}
  113. </body>
  114. </html>

复制代码

 

html 代码

复制代码

  1. {% extends "htmb.html" %}
  2. {% block css %}
  3. <link rel="stylesheet" href="/static/bootstrap/bootstrap-3.3.7-dist/css/bootstrap.min.css">
  4. {% endblock %}
  5. {% block js %}
  6. <script src="/static/js/jquery-1.7.1.min.js"></script>
  7. <script src="/static/js/cmdbzj.js"></script>
  8. <script>
  9. $(function () {
  10. $.NB( '/ajax-date.html')
  11. })
  12. </script>
  13. {% endblock %}
  14. {% block title %}
  15. {% endblock %}
  16. {% block menu %}
  17. {% endblock %}
  18. {% block countent %}
  19. <h1>用户信息</h1>
  20. <div class="btn-group" role="group" aria-label="...">
  21. <button id="bindall" type="button" class="btn btn-default">全选</button>
  22. <button id="bindfx" type="button" class="btn btn-default">反选</button>
  23. <button id="unbindall" type="button" class="btn btn-default">取消</button>
  24. <button id="bindbj" type="button" class="btn btn-default">进入编辑模式</button>
  25. <button type="button" class="btn btn-default">批量删除</button>
  26. <button id='save' type="button" class="btn btn-default">保存</button>
  27. </div>
  28. <table class="table table-bordered table-hover">
  29. <thead id="table_th"></thead>
  30. <tbody id="table_td"></tbody>
  31. </table>
  32. {% endblock %}

复制代码

 

封装的JS代码

复制代码

  1. // 自执行函数
  2. (function () {
  3. requestURL = null;
  4. // {#自定义的 字符format的方法#}
  5. String.prototype.format = function(kwargs){
  6. var ret = this.replace(/\{(\w+)\}/g,function (k,m) {
  7. return kwargs[m]
  8. });
  9. return ret
  10. };
  11. function bindsave(){
  12. $('#save').click(function () {
  13. var postlist=[];
  14. $('#table_td').find('tr[has-edit="true"]').each(function () {
  15. var temp = {};
  16. var id = $(this).attr('j-id');
  17. temp['id'] = id;
  18. $(this).children('[edit-enable="true"]').each(function () {
  19. var name = $(this).attr('name');
  20. var origin = $(this).attr('origin');
  21. var newval = $(this).attr('new-val');
  22. if(origin != newval){
  23. temp[name] = newval;
  24. };
  25. })
  26. postlist.push(temp);
  27. $.ajax({
  28. url:requestURL,
  29. type:'POST',
  30. data:{'post_list':JSON.stringify(postlist)},
  31. dataType:'Json',
  32. success:function (arg) {
  33. if(arg.status){
  34. init(1);
  35. }else {
  36. alter(arg);
  37. }
  38. }
  39. })
  40. })
  41. })
  42. }
  43. function bindM() {
  44. $('#bindbj').click(function () {
  45. var ed = $(this).hasClass('btn-warning');
  46. if(ed){
  47. $(this).removeClass('btn-warning');
  48. $(this).text("进入编辑模式");
  49. $('#table_td').find(':checked').each(function () {
  50. var $cur = $(this).parent().parent();
  51. bjhangout($cur);
  52. })
  53. }else {
  54. $(this).addClass('btn-warning');
  55. $(this).text("退出编辑模式");
  56. $('#table_td').find(':checked').each(function () {
  57. var $cur = $(this).parent().parent();
  58. bjhang($cur);
  59. })
  60. }
  61. })
  62. }
  63. function bindC() {
  64. // {#$('#table_td').find(':checkbox').click()
  65. // 这种方式新增数据无法被选中#}
  66. $('#table_td').on('click',':checkbox',function () {
  67. if($('#bindbj').hasClass('btn-warning')){
  68. var ck = $(this).prop('checked');
  69. var $cur = $(this).parent().parent();
  70. if(ck){
  71. // {#console.log("进入编辑模式");#}
  72. bjhang($cur)
  73. }else{
  74. // {#console.log("退出编辑模式");#}
  75. bjhangout($cur)
  76. }
  77. }
  78. })
  79. }
  80. function bjhang(cur) {
  81. cur.attr('has-edit','true');
  82. cur.children().each(function () {
  83. cur.addClass('success');
  84. var editenable = $(this).attr('edit-enable');
  85. var editetype = $(this).attr('edit-type');
  86. if (editenable === 'true'){
  87. if(editetype === 'select'){
  88. var globalname = $(this).attr("global-name");
  89. var origin = $(this).attr("origin");
  90. var sel = document.createElement('select');
  91. sel.className = "form-control";
  92. $.each(window[globalname],function (k,v) {
  93. var op = document.createElement('option');
  94. op.innerHTML = v[1];
  95. op.setAttribute('value',v[0]);
  96. $(sel).append(op)
  97. });
  98. $(sel).val(origin);
  99. $(this).html(sel);
  100. }else if(editetype === 'input'){
  101. var intext = $(this).text();
  102. var tag = document.createElement('input');
  103. tag.className = "form-control";
  104. tag.value = intext;
  105. $(this).html(tag)
  106. }
  107. }})}
  108. function bjhangout(cur) {
  109. cur.removeClass('success');
  110. cur.children().each(function () {
  111. var editenable = $(this).attr('edit-enable');
  112. if (editenable === 'true'){
  113. var editetype = $(this).attr('edit-type');
  114. if(editetype === 'select'){
  115. var $select = $(this).children().first() ;
  116. var newid = $select.val();
  117. var newtext = $select[0].selectedOptions[0].innerHTML;
  118. $(this).html(newtext);
  119. $(this).attr('new-val',newid)
  120. }else if(editetype === 'input'){
  121. var $input2 = $(this).children().first() ;
  122. var tag2 = $input2.val();
  123. $(this).html(tag2);
  124. $(this).attr('new-val',tag2)
  125. }}})}
  126. function bindall() {
  127. $('#bindall').click(function () {
  128. $('#table_td').find(':checkbox').each(function () {
  129. if($('#bindbj').hasClass('btn-warning')){
  130. if($(this).prop('checked')){
  131. }else {
  132. $(this).prop('checked',true);
  133. var $cur = $(this).parent().parent();
  134. bjhang($cur)
  135. }
  136. }else {
  137. $(this).prop('checked',true);
  138. };
  139. })
  140. })
  141. }
  142. function unbindall() {
  143. $('#unbindall').click(function () {
  144. $('#table_td').find(':checked').each(function () {
  145. if($('#bindbj').hasClass('btn-warning')){
  146. $(this).prop('checked',false);
  147. var $cur = $(this).parent().parent();
  148. bjhangout($cur);
  149. }else {
  150. $(this).prop('checked',false);
  151. }
  152. })
  153. })
  154. }
  155. function bindfx() {
  156. $('#bindfx').click(function () {
  157. $('#table_td').find(':checkbox').each(function () {
  158. if($('#bindbj').hasClass('btn-warning')){
  159. var $cur = $(this).parent().parent();
  160. if ($(this).prop('checked')){
  161. $(this).prop('checked',false);
  162. bjhangout($cur);
  163. }else {
  164. $(this).prop('checked',true);
  165. bjhang($cur);
  166. }
  167. }else {
  168. if ($(this).prop('checked')){
  169. $(this).prop('checked',false);
  170. }else {
  171. $(this).prop('checked',true);
  172. }
  173. }
  174. })
  175. })
  176. }
  177. // {#用ajax get方式获取后台的json数据#}
  178. function init(pager) {
  179. $.ajax(
  180. {
  181. url:requestURL,
  182. data:{'pager':pager},
  183. type:'GET',
  184. dataType:'JSON',
  185. success:function (result) {
  186. initchoice(result.choice_dict);
  187. initheader(result.table_config);
  188. initbody(result.table_config,result.info)
  189. }
  190. }
  191. )
  192. };
  193. // {#列表表头显示部分#}
  194. function initheader(table_config) {
  195. var tr = document.createElement('tr');
  196. $.each(table_config,function (k,item) {
  197. var th = document.createElement('th');
  198. if (item.display){
  199. th.innerHTML = item.title;
  200. $(tr).append(th);
  201. }
  202. });
  203. $('#table_th').empty();
  204. $('#table_th').append(tr);
  205. }
  206. // {#列表数据显示部分#}
  207. function initbody(table_config,info){
  208. $('#table_td').empty();
  209. $.each(info,function (i,j) {
  210. var tr = document.createElement('tr');
  211. tr.setAttribute('j-id',j['id']);
  212. var dictinfo = {};
  213. $.each(table_config,function (x,y) {
  214. if (y.display) {
  215. $.each(y.text.val,function (k,v) {
  216. if(v.substring(0,2) ==='@@'){
  217. var gname = v.substring(2,v.length);
  218. var gid = j[y.id];
  219. var t = test(gname,gid);
  220. dictinfo[k] =t;
  221. }else if (v[0] ==='@'){
  222. dictinfo[k] = j[v.substring(1,v.length)];
  223. }else {
  224. dictinfo[k] = v;}
  225. });
  226. var td = document.createElement('td');
  227. var ss = y.text.key.format(dictinfo);
  228. td.innerHTML = ss;
  229. $.each(y.attrs,function (q,t) {
  230. if(t[0] === '@'){
  231. td.setAttribute(q,j[t.substring(1,t.length)]);
  232. }else {
  233. td.setAttribute(q,t)
  234. }
  235. });
  236. $(tr).append(td);}
  237. });
  238. $('#table_td').append(tr)})}
  239. // {#choice数据类型,定义全局变量#}
  240. function initchoice(choice_dict) {
  241. $.each(choice_dict,function (i,j) {
  242. window[i]=j;
  243. })
  244. }
  245. // {#将以数据id去choice全局变量取对应的 中文显示信息#}
  246. function test(gname,gid) {
  247. var ret = null;
  248. $.each(window[gname], function (k, item) {
  249. if (item[0] === gid) {
  250. ret = item[1];
  251. return
  252. }
  253. });
  254. return ret;
  255. }
  256. jQuery.extend({
  257. 'NB':function (url) {
  258. requestURL = url;
  259. init();
  260. bindM();
  261. bindC();
  262. bindall();
  263. unbindall();
  264. bindfx();
  265. bindsave();
  266. },
  267. 'changepager':function (num) {
  268. init(num);
  269. }
  270. })
  271. })();

复制代码

   views完整代码

复制代码

  1. def ajaxdate(request):
  2. import json
  3. if request.method == "GET":
  4. table_config = [
  5. {
  6. 'id': None,
  7. 'title': '选项',
  8. 'display': 1,
  9. 'text': {'key': "<input type='checkbox' />", 'val': {}},
  10. 'attrs': {},
  11. },
  12. {
  13. 'id':'id',
  14. 'title':'ID',
  15. 'display':1,
  16. 'text':{'key':"{n}",'val':{'n':'@id'}},
  17. 'attrs':{},
  18. },
  19. {
  20. 'id': 'title',
  21. 'title': '标题',
  22. 'display': 1,
  23. 'text': {'key': "{n}", 'val': {'n': '@title'}},
  24. 'attrs': {'name':'title',"origin":'@title','edit-enable':'true','edit-type':'input'},
  25. },
  26. {
  27. 'id': 'status',
  28. 'title': '状态',
  29. 'display': 1,
  30. 'text': {'key': "{n}", 'val': {'n': '@@device_type_choice'}},
  31. 'attrs': {'name':'status',"origin":'@status','edit-enable':'true','edit-type':'select',"global-name":'device_type_choice'},
  32. },
  33. {
  34. 'id': 'pro_id',
  35. 'title': '处理人',
  36. 'display': 1,
  37. 'text': {'key': "{n}", 'val': {'n': '@@device_type_userinfo'}},
  38. 'attrs': {'name':'pro_id',"origin":'@pro_id','edit-enable':'true','edit-type':'select',"global-name":'device_type_userinfo'},
  39. },
  40. {
  41. 'id': 'sol',
  42. 'title': '处理详情',
  43. 'display': 1,
  44. 'text': {'key': "{n}", 'val': {'n': '@sol'}},
  45. 'attrs': {'name': 'sol', "origin": '@sol', 'edit-enable': 'true', 'edit-type': 'input'},
  46. },
  47. {
  48. 'id': None,
  49. 'title': '操作',
  50. 'display': 1,
  51. 'text': {'key': "<a href='#'>添加</a>|<a href='#'>删除</a>", 'val': {}},
  52. 'attrs': {},
  53. },
  54. ]
  55. zd = []
  56. for i in table_config:
  57. if i['id']:
  58. zd.append(i['id'])
  59. info = models.Fault.objects.values(*zd).all()
  60. choice = models.Fault.choice
  61. userinfo = models.Userinfo.objects.all().values_list('uid','uname')
  62. result = {
  63. 'table_config':table_config,
  64. 'info':list(info),
  65. 'choice_dict':{'device_type_choice':choice,'device_type_userinfo':list(userinfo)},
  66. }
  67. return HttpResponse(json.dumps(result))
  68. elif request.method == "POST":
  69. content = json.loads(request.POST['post_list'])
  70. if content:
  71. for i in content:
  72. models.Fault.objects.filter(id=i['id']).update_or_create(i)
  73. ret = {'status':'OK'}
  74. return HttpResponse('OK')

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/1021129
推荐阅读
相关标签
  

闽ICP备14008679号