第八章、只读字段处理和filter_horizontal的实现
8.1.只读字段的处理
(1)kingadmin/admin_base.py
# kingadmin/admin_base.pyclass BaseKingAdmin(object): list_display = [] list_filter = [] search_fields = [] #只读 readonly_fields = []
(2)crm/kingadmin.py
(3)kingadmin/form_handle.py
(4)table_obj_change_component.html
{#kingadmin/templates/kingadmin/table_obj_change_component.html#}{% load kingadmin_tags %}
(5)kingadmin_tags.py
@register.simple_tagdef get_obj_field_val(form_obj,field): '''获取只读字段的值''' return getattr(form_obj.instance,field)
现在修改的时候没问题,但是在添加的时候会报错(提示那两个只读字段为空,因为设置成了readonly_field,添加的时候确实没有添加值)
下面解决这个报错,在前后端都添加一个判断
(4)kingadmin/views.py
(5)form_handle.py
(6)table_obj_change_component.html
现在增加和修改就都没问题了
8.2.filter_horizontal的实现
默认咨询课程后台显示的样子
添加filter_horizontal(数据量大的时候很方便)后显示的样子(可以批量添加,还可以在里面搜索)
下面我们在kingadmin中实现这个功能
(1)kingadmin/admin_base.py
# kingadmin/admin_base.pyclass BaseKingAdmin(object): list_display = [] list_filter = [] search_fields = [] #只读 readonly_fields = [] filter_horizontal = []
(2)crm/kingadmin.py
(3)kingadmin/kingadmin_tags.py
@register.simple_tagdef get_available_m2m_data(field_name,admin_class): '''返回的是m2m字段关联表的所有数据''' #获取字段的对象 field_obj = admin_class.model._meta.get_field(field_name) #consult_courses = models.ManyToManyField('Course',verbose_name='咨询课程') #consult_courses是一个m2m,通过consult_courses对象获取到Course(也就是获取到所有咨询的课程) obj_list = field_obj.related_model.objects.all() return obj_list
(4)table_obj_change_component.html
- 在生成field的时候判断在不在filter_horizontal里面,在的话就用我们设置的select下拉框,不在就默认的
- {% get_available_m2m_data field.name admin_class as available_m2m_data %} 后面的的 as availavle_m2m_data 是定义一个变量(里面存了自定义模板标签里面返回的数据 return obj_list)
因为在前端不能直接循环从后台返回的querysets数据(obj_list),所以前端在引用自定用模板标签的时候可以定义一个变量,里面就保存了所有后台传过来的数据
{#kingadmin/templates/kingadmin/table_obj_change_component.html#}{% load kingadmin_tags %}
效果:
右边添加一个select框(存放已选中的)
kingadmin_tags.py
@register.simple_tagdef get_selected_m2m_data(field_name,form_obj,admin_class): '''返回已选的m2m数据''' #获取被选中的数据 selected_data = getattr(form_obj.instance,field_name).all() return selected_data
table_obj_change_component.html
效果:
- 左边不应该显示已被选中的咨询课程了
- 右边是已选中的咨询课程
通过集合求差集过滤出左边已选咨询课程
kingadmin_tags.py
@register.simple_tagdef get_available_m2m_data(field_name,form_obj,admin_class): '''返回的是m2m字段关联表的所有数据''' #获取字段的对象 field_obj = admin_class.model._meta.get_field(field_name) #consult_courses = models.ManyToManyField('Course',verbose_name='咨询课程') #consult_courses是一个m2m,通过consult_courses对象获取到Course(也就是获取到所有咨询的课程) #所有咨询课程的集合 obj_list = set(field_obj.related_model.objects.all()) #选中的咨询课程集合 selected_data = set(getattr(form_obj.instance, field_name).all()) #返回的时候,集合求差集,得到未选中的咨询课程(左边) return obj_list - selected_data
效果:
js触发事件
table_obj_change_component.html
可以通过双击咨询课程,来选择
{#kingadmin/templates/kingadmin/table_obj_change_component.html#}{% load kingadmin_tags %}
现在保存的时候没有问题,但是 添加的时候会报错(因为添加的时候,值都是为空,获取不到filter_horizontal的值所有报错),下一章解决