Python CRM项目四

实现Django Admin的多对多的复选框效果

效果:左边显示的是未选中的字段,右边显示的是已选中的字段,两边点击的标签可以互相更换

首先在king_admin.py中增加filter_horizontal字段

1 class CustomerAdmin(BaseAdmin):
2     list_display = ['qq','name','source','consultant','consult_course','date','status']
3     list_filters = ['source','consultant','consult_course','status','date']
4     search_fields = ['qq','name','consultant__name']
5     list_per_page = 5
6     ordering = 'id'
7     filter_horizontal = ['tags',]
View Code

在views中不需要进行修改

在页面增加复选框的样式和相应的标签

 1 <div class="col-sm-5" style="340px">
 2                             {% if field.name in admin_class.filter_horizontal %}
 3 {#                                实现和Django类似的复选框#}
 4                                 <div class="col-md-4">
 5                                     {% get_m2m_tags  admin_class field form_obj as m2m_obj_tags%}
 6                                     <select multiple class="filter-select-box-left" id="id_{{ field.name }}_from">
 7                                         {% for obj_tag in  m2m_obj_tags%}
 8                                             <option ondblclick="move_element(this,'id_{{ field.name }}_to','id_{{ field.name }}_from')" value="{{ obj_tag.id }}">{{ obj_tag }}</option>
 9                                         {% endfor %}
10                                     </select>
11                                 </div>
12                                 <div class="col-md-4">
13                                     {% get_m2m_selected_tags form_obj field as select_tags%}
14                                     <select tag="choose_list" multiple name="{{ field.name }}"class="filter-select-box-right" id="id_{{ field.name }}_to">
15                                         {% for obj_tag in  select_tags %}
16                                             <option ondblclick="move_element(this,'id_{{ field.name }}_from','id_{{ field.name }}_to')" value="{{ obj_tag.id }}">{{ obj_tag }}</option>
17                                         {% endfor %}
18                                     </select>
19                                 </div>
20                             {% else %}
21                                 {{ field }}
22                             {% endif %}
23                         </div>
View Code

在页面的css中修改复选框的样式

 1 {% block css %}
 2 <style type="text/css">
 3     .filter-select-box-left{
 4         height:160px!important;
 5         120px;
 6         margin-right:10px;
 7         border-re
 8     }
 9  .filter-select-box-right{
10         height:160px!important;
11         120px;
12         margin-left:60px;
13     }
14 </style>
15 
16 {% endblock %}
View Code

在页面的js中增加点击事件,点击复选框内的元素可以实现互相转移

思路:将左边复选框中的option节点删除,右边复选框的option节点增加

1 function move_element(ths,target_id,new_target_id){
2         //移动思路:删除左边当前标签,在右边添加当前标签
3         var opt_ele = "<option value='" + $(ths).val() + "' ondblclick=move_element(this,'"+new_target_id+"','"+target_id+"')>" + $(ths).text()+"</option>"
4 
5         //$(ele).off().ondblclick();
6         //$(ele).appendTo("#"+target_id);
7         $('#'+target_id).append(opt_ele);
8         $(ths).remove();
9     }
View Code

同时在提交的时候,将右边的复选框的所有元素全选,然后提交

首先给form表单添加onsubmit事件

1     //循环右边所有的元素,然后全选
2     function select_all_choose(){
3         $('select[tag="choose_list"] option').each(function(){
4             $(this).prop("selected",true);
5         })
6         return true;
7     }
View Code

在tag自定义标签中,实现后台渲染返回到前端

右边的复选框:返回记录中已选的tags

思路:通过getattr从当前的form_obj.instance和列名中获取到已选的tags对象

1 @register.simple_tag
2 def get_m2m_selected_tags (form_obj,field):
3     #返回已选中的复选框数据
4     if form_obj.instance.id:
5         field_obj = getattr(form_obj.instance,field.name)
6         return field_obj.all()
View Code

左边的复选框:返回记录没有选择的tags

思路:获取数据库全部的tags和已选的tags,然后循环,如果不是已选的tags则放入到一个新的列表,返回

 1 @register.simple_tag
 2 def get_m2m_tags(admin_class,field,form_obj):
 3     #返回多对多所有待选数据
 4 
 5     #表结构对象的多对多字段
 6     all_field_obj = getattr(admin_class.model,field.name)
 7     #全部多对多字段
 8     all_field_list = all_field_obj.rel.to.objects.all()
 9 
10     if form_obj.instance.id:#判断记录是否有多对多对象,如果没有则是新建,有就是修改
11         # 已选数据的多对多对象
12         choose_field_obj = getattr(form_obj.instance, field.name)
13         #已选数据的多对多字段
14         selected_obj_list = choose_field_obj.all()
15     else: #表示创建新的记录
16         return all_field_list
17 
18     standby_obj_list = []
19     for obj in all_field_list:
20         if obj not in selected_obj_list:
21             standby_obj_list.append(obj)
22 
23 
24     return standby_obj_list
View Code
原文地址:https://www.cnblogs.com/luhuajun/p/7846163.html