一、本节目标
前几节我们开发了数据展示,数据增删改查,只读字段处理等,本节我们开发可以左右移动选择的多选框
二、功能分析
1、对于多选框,admin的实现方式是,在自定义admin里,添加filter_horizontal,然后在admin里可以看见,有一个可以左右选择的多选框,可以左右移动选项来进行选择。
添加功能也是如此:
查看后台,可以发现,其实是放到了select选择框里:
三、功能开发
1、在baseadmin里添加对应字段:
2、在自定义admin里添加要左右选择的字段
3、接下来开发:
目前是这么展示的:
要变成这样展示:
需要把这个字段的数据全部取出来,然后放到select框里。由于这里是多对多:
取出数据的方法如下实验:
from crm import models
field_obj = models.CustomerInfo._meta.get_field(‘consult_courses‘)
print(field_obj)
obj_list = field_obj.related_model.objects.all()
print(obj_list)
输出:
先取出此字段对应的对象,是一个表中的字段,然后根据这个对象查找出关联表的数据。
这里因为有下划线,因此还是放到tag里:
4、前端页面修改,先修改修改页面table_obj_change,主要是做了一个判断,如果是左右移动选择框里的内容,就显示在自定义的select框里:
效果如图:
5、在右边添加一个select框,存放已选中的项,已选中的项的数据,还是上边那种获取方法:
修改前端页面,这里修改修改页面table_obj_change:
效果:
已经可获取,但是还需完善,左边不显示已经被选择过的
6、完善左边多选框里,已经被选中的项目,让其不再显示
因此,这里需要修改一下获取所有选择项这里:
这里用到集合的求差集的方法,以前觉得没有用的功能,这里就派上了用场,所有的基本知识点都有用,都需要牢记:
selected_data = {‘python‘}
all_data = {‘python‘,‘go‘}
print(all_data)
print(all_data - selected_data)
输出:
修改tag
此时效果如图:
7、开发点击左右选择的功能,可以通过双击咨询课程,来选择:
<form class="form-horizontal" method="post" onsubmit="VerificationBeforeFormSubmit()">
{% csrf_token %}
{{ form_obj.errors }}
{% for field in form_obj %}
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">{{field.label}}</label>
<div class="col-sm-10">
<!--可供选择的-->
{% if field.name in admin_class.filter_horizontal %}
<div class="col-lg-5">
<select id="id_{{ field.name }}_from" multiple class="form-control">
{% get_available_m2m_data field.name admin_class form_obj as available_m2m_data %}
{% for obj in available_m2m_data %}
<option ondblclick="MoveSelectedOption(this,‘id_{{ field.name }}_to‘)" value="{{ obj.id }}">{{ obj }}</option>
{% endfor %}
</select>
</div>
<!--已选中的-->
<div class="col-lg-5">
<select tag="selected_m2m" id="id_{{ field.name }}_to" multiple class="form-control" name="{{field.name}}">
{% get_selected_m2m_data field.name form_obj admin_class as selected_m2m_data %}
{% for obj in selected_m2m_data %}
<option value="{{ obj.id }}" ondblclick="MoveSelectedOption(this,‘id_{{ field.name }}_from‘)">{{ obj }}</option>
{% endfor %}
</select>
</div>
<div class="col-lg-5"></div>
{% else %}
{{ field }}
{% endif %}
<span style="color: red">{{ field.errors.0 }}</span>
</div>
</div>
{% endfor %}
{% for field in admin_class.readonly_fields %}
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">{{field}}</label>
<div class="col-sm-10">
{% comment %} {{ field }}{% endcomment %}
<p>{% get_obj_field_value form_obj field %}</p>
</div>
</div>
{% endfor %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-info">save</button>
</div>
</div>
</form>
</body>
<script>
function MoveSelectedOption(ele,target_id) {
var new_target_id = $(ele).parent().attr(‘id‘);
var option = "<option value=‘" + $(ele).val() +"‘ondblclick=MoveSelectedOption(this,‘"+ new_target_id +"‘) >" + $(ele).text() +"</option>";
$("#"+ target_id).append(option);
$(ele).remove();
}
function VerificationBeforeFormSubmit() {
$("select[tag] option").prop(‘selected‘,true);
}
</script>