您现在的位置是: 网站首页 >Django >DjangoCRM客户关系管理 Django
【CRM客户关系管理】17.多选字段filter_horizontal的实现,已选和未选数据展示
admin2018年12月23日 15:20 【Django | JavaScript | JQuery | Python 】 1106人已围观
DjangoCRM客户关系管理简介 使用Django2.1.3+Bootstrap实现CRM系统,仿照Django Admin重写后台 Github地址:https://github.com/xyliurui/DjangoCRM Django版本:2.1.3
## 多选字段filter_horizontal的实现 ### Django Admin实现方式 Django admin后台显示效果 在admin.py中注册 ```python class CustomerInfoAdmin(admin.ModelAdmin): list_display = ['name', 'contact_type', 'contact', 'consultant', 'consult_content', 'status', 'created_time'] list_filter = ['source', 'consultant', 'status', 'created_time'] search_fields = ['contact', 'consultant__name', 'consult_content'] readonly_fields = ['contact', 'status'] filter_horizontal = ['consult_courses'] admin.site.register(CustomerInfo, CustomerInfoAdmin) ``` 如果没有`filter_horizontal = ['consult_courses']`,效果如下 ![BLOG_20181223_152140_22](/media/blog/images/2018/12/BLOG_20181223_152140_22.png "博客图集BLOG_20181223_152140_22.png") 如果有,效果如下 ![BLOG_20181223_152159_13](/media/blog/images/2018/12/BLOG_20181223_152159_13.png "博客图集BLOG_20181223_152159_13.png") 当数据量很大的时候,可以通过搜索批量添加。 ### djadmin中实现filter_horizontal #### 在父类和子类中添加filter_horizontal字段 首先在djadmin应用djadmin_base.py中添加`filter_horizontal`空列表 ```python # djadmin/djadmin_base.py class BaseDjAdmin(object): list_display = [] list_filter = [] search_fields = [] readonly_fields = [] filter_horizontal = [] ``` 修改crm应用的djadmin.py增加`filter_horizontal`字段 ```python # 注册model class CustomerInfoAdmin(BaseDjAdmin): # 不使用object,直接继承BaseDjAdmin list_display = ['name', 'contact_type', 'contact', 'consultant', 'consult_content', 'status', 'created_time'] list_filter = ['source', 'consultant', 'status', 'created_time'] search_fields = ['contact', 'consultant__name', 'consult_content'] readonly_fields = ['contact', 'status'] filter_horizontal = ['consult_courses'] site.register(models.CustomerInfo, CustomerInfoAdmin) ``` #### 获取多对多关联表数据 修改djadmin应用的模板标签djadmin_tags.py,增加获取多对多字段关联表的所有数据 ```python @register.simple_tag def get_available_m2m_data(field_name, admin_class): """获取多对多字段关联表的所有数据""" field_obj = admin_class.model._meta.get_field(field_name) # 获取字段对象 # consult_courses = models.ManyToManyField(Course, verbose_name='咨询课程') # 多对多关联课程 # 这是一个多对多字段,通过consult_courses对象获取到Course,也就是获取到所有咨询的课程 obj_list = field_obj.related_model.objects.all() return obj_list ``` #### 模板中展示多选框 修改djadmin应用templates/djadmin/table_edit.html,当遍历的字段在多选列表内,就使用多选的样式 `{% get_available_m2m_data field.name admin_class as available_m2m_data %}` 后面的的 `as availavle_m2m_data` 是定义一个变量(里面存了自定义模板标签里面返回的数据 `return obj_list`) 因为在前端不能直接循环从后台返回的queryset数据(obj_list),所以前端在引用自定用模板标签的时候可以定义一个变量,里面就保存了所有后台传过来的数据 ```html {% extends 'djadmin/base.html' %} {% load djadmin_tags %} {% block title %} 数据表编辑 - 后台管理 {% endblock %} {% block content %} <h1 class="page-header">{{ app_name }} - {{ model_name }} - 编辑 {{ obj }} </h1> <!--<div>{{ form_obj }}</div>--> <form class="form-horizontal" method="post"> {{ form_obj.errors }} {% for field in form_obj %} <div class="form-group"> <label 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-md-5"> <select multiple class="form-control"> {% get_available_m2m_data field.name admin_class as vailable_m2m_data %} {% for obj in vailable_m2m_data %} <option value="{{ obj.id }}">{{ obj }}</option> {% endfor %} </select> </div> {% else %} {{ field }} {% endif %} <span style="color: red">{{ field.errors.0 }}</span> </div> </div> {% endfor %} {% csrf_token %} {% if not admin_class.form_add %} {# 当修改数据时,才显示下方只读字段,当增加数据时,下方则不会显示 #} {% for field in admin_class.readonly_fields %} <label class="col-sm-2 control-label">{{ field }}</label> <div class="col-sm-10"> <p>{% get_obj_field_val form_obj field %}</p> </div> {% endfor %} {% endif %} <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-primary">提交</button> </div> </div> </form> {% endblock %} ``` 访问 http://127.0.0.1:8000/djadmin/crm/customerinfo/1/change/ 发现,选择列表都显示在该框内了 ![BLOG_20181223_152309_65](/media/blog/images/2018/12/BLOG_20181223_152309_65.png "博客图集BLOG_20181223_152309_65.png") #### 已选择数据展示右方 现在需要在右边增加一个select框,用于存放已选中的,修改djadmin_tags.py增加一个模板标签,用来获取已选择的数据 ```python @register.simple_tag def get_selected_m2m_data(field_name, form_obj, admin_class): """获取已选中的多对多数据""" selected_data = getattr(form_obj.instance, field_name).all() return selected_data ``` 在table_edit.html多选框右边增加已选中数据 ```html <div class="col-sm-10"> {% if field.name in admin_class.filter_horizontal %} <!--字段名在多选的字段中,使用多选框--> <div class="col-md-5"> <select multiple class="form-control"> {% get_available_m2m_data field.name admin_class as vailable_m2m_data %} {% for obj in vailable_m2m_data %} <option value="{{ obj.id }}">{{ obj }}</option> {% endfor %} </select> </div> <div class="col-md-5"> <select multiple class="form-control"> {% get_selected_m2m_data field.name form_obj admin_class as selected_m2m_data %} {% for obj in selected_m2m_data %} <option value="{{ obj.id }}">{{ obj }}</option> {% endfor %} </select> </div> {% else %} {{ field }} {% endif %} <span style="color: red">{{ field.errors.0 }}</span> </div> ``` ![BLOG_20181223_152407_68](/media/blog/images/2018/12/BLOG_20181223_152407_68.png "博客图集BLOG_20181223_152407_68.png") 现在右边已经显示已选中的数据,但是左边不应该显示已被选中的数据,需要进行排序 #### 未选择数据展示左方 修改table_edit.html,将`form_obj`传给获取可选数据的模板标签中 ```html <div class="col-md-5"> <select multiple class="form-control"> {% get_available_m2m_data field.name form_obj admin_class as vailable_m2m_data %} {% for obj in vailable_m2m_data %} <option value="{{ obj.id }}">{{ obj }}</option> {% endfor %} </select> </div> ``` 通过集合求差集过滤排除左边已选咨询课程数据 ```python @register.simple_tag def get_available_m2m_data(field_name, form_obj, admin_class): """获取多对多字段关联表的所有数据""" field_obj = admin_class.model._meta.get_field(field_name) # 获取字段对象 # consult_courses = models.ManyToManyField(Course, verbose_name='咨询课程') # 多对多关联课程 # 这是一个多对多字段,通过consult_courses对象获取到Course,也就是获取到所有咨询的课程 obj_list = field_obj.related_model.objects.all() obj_list = set(obj_list) # 所有咨询课程的集合 selected_data = set(getattr(form_obj.instance, field_name).all()) # 所以已选中课程的即可 # 通过集合求差集,得到未选中的自选课程,填充到左边多选框中 return obj_list - selected_data ``` ![BLOG_20181223_152441_59](/media/blog/images/2018/12/BLOG_20181223_152441_59.png "博客图集BLOG_20181223_152441_59.png")
很赞哦! (0)
相关文章
文章交流
- emoji
当前用户
未登录,点击 登录专题目录
- 【CRM客户关系管理】01.项目介绍分析
- 【CRM客户关系管理】02.设置项目需要的模型
- 【CRM客户关系管理】03.使用Bootstrap前端模板
- 【CRM客户关系管理】04.用户登录登录及访问控制
- 【CRM客户关系管理】05.动态菜单生成,绝对URL和动态URL
- 【CRM客户关系管理】06.创建djadmin APP,并进行相关配置
- 【CRM客户关系管理】07.自动发现APP注册并显示列表
- 【CRM客户关系管理】08.取出app中model的值,根据list_display配置生成数据列表
- 【CRM客户关系管理】09.根据模型中字段的choices以及时间区间来过滤数据
- 【CRM客户关系管理】10.处理无list_display和list_filter属性时的异常情况
- 【CRM客户关系管理】11.为查询结果添加分页和排序功能
- 【CRM客户关系管理】12.查询结果分页、排序、过滤组合
- 【CRM客户关系管理】13.为结果添加搜索功能,搜索后能对其进行过滤
- 【CRM客户关系管理】14.生成动态ModelForm表单功能
- 【CRM客户关系管理】15.动态ModelsForm增加自定义样式,修改初始化表单并提交
- 【CRM客户关系管理】16. 只读字段readonly_fields处理,表单排除只读显示
- 【CRM客户关系管理】17.多选字段filter_horizontal的实现,已选和未选数据展示
- 【CRM客户关系管理】18.多选字段filter_horizontal的实现,js移动多选框数据和过滤
- 【CRM客户关系管理】19.对象删除功能,显示删除的关联对象和确认
- 【CRM客户关系管理】20.增加详情页分页功能
- 【CRM客户关系管理】21.action功能开发,默认action,生成自己的action
- 【CRM客户关系管理】22.action功能开发,执行action功能,添加默认的delete action