关于django2.0+Xadmin 后台页面多级联动的尝试

小弟第一次发帖,有什么不对的,请各位大大海涵。
问题:如何实现django2.0+Xadmin 后台页面的多级联动(本例为二级联动)

简单说一下自己的思路

  1. 先找到控件id ,这样就可以监听change事件
  2. 然后把自己写的js加入xadmin中
  3. 添加url和view,接受ajax请求和发送数据

第一步:找到联动的上下级select 的 id
id就在页面里F12就可以查看,我直接贴上了
父级ID 为id_courses

<select name="courses" class="adminselectwidget form-control selectized" required="" id="id_courses" tabindex="-1" style="display: none;"><option value="4" selected="selected">rfedr3r</option></select>

子级ID 为id_lesson

<select name="lesson" class="adminselectwidget form-control selectized" required="" id="id_lesson" tabindex="-1" style="display: none;"><option value="" selected="selected"></option></select>

 

好的,现在我们找到了上下级id  id_courses和id_lesson

第二步:ajax请求(单纯的js知识,不会的童鞋可以去简单了解下jquery 的ajax方法)

 直接贴代码了

$('#id_courses').change(function () {
        var module = $('#id_courses').find('option:selected').val(); //获取父级选中值
        $('#id_lesson')[0].selectize.clearOptions();// 清空子级
        $.ajax({
            type: 'get',
            url: '/select/course_lesson/?module=' + module,
            data: '',
            async: true,
            beforeSend: function (xhr, settings) {
                xhr.setRequestHeader('X-CSRFToken', '{{ csrf_token }}')
            },
            success: function (data) {
                data = JSON.parse(data.lesson)//将JSON转换

                for (var i = 0; i < data.length; i++) {

                    var test = {text: data[i].fields.name, value: data[i].pk, $order: i + 1}; //遍历数据,拼凑出selectize需要的格式
                    console.log(test)
                    $('#id_lesson')[0].selectize.addOption(test); //添加数据
                }
            },
            error: function (xhr, textStatus) {
                console.log('error')
            }
        })
    })

这里面有几个函数需要说明下 ,因为我们的select控件数据加载是受selectize.js控制的,详见xadmin/static/xadmin/vendor/selectize

我们使用了xadmin自带的selectize.js中的方法

  1. selectize.clearOptions()清空内容
  2. selectize.addOption() 添加数据

我写的js代码很简单,只是基本实现了联动功能,有些细节的部分,欢迎大家指出补充 

第三步:将js放入xadmin中

这一步很简单,但是小弟我研究了好久才发现的,现在觉得有人领路要少走很多弯路

将自己写的js代码命名为xadmin.js,名字随便起,简单易懂就行

放入xadmin/static/xadmin/js中,我的xadmin是直接放在项目里的,方便修改

最激动人心的时刻到了,我们如何让xadmin引入我们的写的js呢?

我也不会

嘿嘿,不卖关子了,如下

这个挨千刀的就在这里,小弟一个人瞎琢磨才发现这里的奥妙

wiget 里面控制加载控件的js,我们只需找到AdminSelectWidget这个类,向里面加入我们的js即可,具体方法如下

class AdminSelectWidget(forms.Select):

    @property
    def media(self):
        return vendor('select.js', 'select.css', 'xadmin.widget.select.js', 'xadmin.js')

这样xadmin.js就被我加入到select控件中了,但是有个小问题就是所有的select控件都会加载这个js,有没有大佬能够修改下呢 

离革命胜利只差一步之遥了,同志们,加把劲

第四步:添加url,我们写的ajax请求需要后台处理数据

view.py 

#导入serializers
from django.core import serializers
# 二级联动View函数
class SelectView(LoginRequiredMixin, View):
    def get(self, request):
        # 通过get得到父级选择项
        course_id = request.GET.get('module', '')
        # 筛选出符合父级要求的所有子级,因为输出的是一个集合,需要将数据序列化 serializers.serialize()
        lessons = serializers.serialize("json", Lesson.objects.filter(courses_id=int(course_id)))
        # 判断是否存在,输出
        if lessons:
            return JsonResponse({'lesson': lessons})

url.py

导入view函数
from users.views import  SelectView
 # 二级联动页面请求
    path('select/course_lesson/', SelectView.as_view(), name='course_lesson'),

第五步:你已经实现了二级联动了,如果你要实现三级四级五级联动,只需修改js和view.py代码即可,小弟在这里抛砖引玉,欢迎各位大佬多提意见。 

 

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页