重写django xadmin后台的新增数据模板

本文介绍如何在xadmin后台不使用ManyToManyField情况下,通过自定义模板和JavaScript实现公司列表的多选、全选及搜索功能,并保存数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在xadmin后台不使用ManyToManyField的情况下实现多对多操作,目的效果如下:
在这里插入图片描述
目的是将左边的公司列表可以多个或者全选加到右边,但是如果不使用ManyToManyField是不能出现上面的效果,只能这样,手动输入公司
在这里插入图片描述
在网上找了好久之后,发现无法实现这种控件操作,但是又想使用xadmin的数据保存、页面显示跳转等功能,只能重新写这个页面了,不过重写并不复杂,主要就是ctrl+c/v,那么开始操作吧

一、新建模板,替换原页面的模板

在pycharm中新建一个HTML文件,删掉所有信息,继承xadmin底层的表单模板

{% extends 'xadmin/views/model_form.html' %}

在这里插入图片描述
然后我们用这个模板把我们现在看到的替换掉,在adminx.py中你创建的那个类中加入一行代码

add_form_template = 'xxx.html'
二、重写模板

首先我们可以看一下这个model_form.html的结构
在这里插入图片描述
这是它的基本框架,我们要修改的就是他的content部分,所以把{% block content %}{% endblock %}部分复制到我们的模板中,同时打开目前我们的网页,将整个form部分copy进去
在这里插入图片描述
在这里插入图片描述
再看一下我们想要重新的部分如下:
在这里插入图片描述
先在xadmin后台看一下我们现在的网页中要修改的这一部分的class,我们可以通过选择器找到红框中的目标
在这里插入图片描述
那么就去使用过ManyToManyField生成的页面下把这部分代码copy出来,打开一个xadmin后台,找到之后复制element,粘贴到我们的form中< div class="controls " >的位置,同时把它的样式也复制到我们的content中
在这里插入图片描述
在这里插入图片描述
我把样式贴在这里:

<style>
    .control-wrap{
        display: block;
        width: 100%;
        padding-right: 45px;
    }

    .selector{
        position: relative;
        float: left;
        overflow: hidden;
        width: 100%;
    }

    .selector-available,.selector-chosen{
        border: 1px solid #ddd;
        background-color: #eee;
        float: left;
        width: 45%;
    }

    .selector p.title{
        padding: 7px 5px 0 7px;
        font-size: 14px;
        line-height: 13px;
        font-weight: bold;
    }

    p{
        margin: 0 0 10px;
    }

    .selector .selector-filter{
        width: 100%;
    }

    .input-group{
        position: relative;
        display: table;
        border-collapse: separate;
    }

    .selector select[multiple=multiple]{
        border-left: 0;
        border-top: 1px solid #d0d0d0;
        border-bottom: 1px solid #d0d0d0;
        margin: 0;
        padding-left: 3px;
        width: 100%;
        height: 200px;
        display: block;
        max-width: none !important;
    }

    a.selector-chooseall,a.selector-clearall{
        border-top: 1px solid #e4e4e4;
        display: block;
        margin: 0;
        padding: 2px 7px;
        font-size: 11px;
        line-height: 20px;
        font-weight: bold;
    }

    .selector ul.selector-chooser{
        float: left;
        margin: 100px 2px 0;
        padding: 0;
        width: 31px;
        list-style: none;
    }

    .selector ul.selector-chooser li{
        margin-top: 10px;
    }

    .selector .selector-chosen select[multiple=multiple]{
        height: 230px;
    }

</style>

这个时候再去刷新网页,我们可以看到模板以及变成我们想要的了
在这里插入图片描述

三、导入公司列表

接下来就是怎么把我们要全选的公司列表导入到可用项,那就要用到js了,我们可以在页面上看到公司列表是位于select多选框中的
在这里插入图片描述
首先,在后台写好返回所有公司的接口,在模板中添加js

//从后台请求到公司,添加到页面的select中
    $(document).ready(function () {
        $.getJSON('接口',function (data) {
            if(data.status == 0){
                for(var i=0;i<data.data.length;i++){
                    var dzobj = data.data[i];
                    $('#id_company_form').append("<option value='"+dzobj.公司id+"'>"+dzobj.公司名称+"</option>");
                }
            }
        })
    });

刷新页面,我们可以看到公司已经出来了,接着就是添加单击添加、选择全部、删除全部、搜索几个功能的js了,我就直接把js贴在这里了

    // 添加公司
    $('#id_company_form').dblclick(function () {
        $('#id_company_form option').each(function () {
            if(this.selected == true){
                $('#id_com_list').append(this);
            }
        });

        if($('#id_company_form option').length == 0){
            $('.selector-chooseall').addClass('disabled')
        }else {
            $('.selector-chooseall').removeClass('disabled')
        }

        if($('#id_com_list option').length == 0){
            $('.selector-clearall').addClass('disabled')
        }else {
            $('.selector-clearall').removeClass('disabled')
        }
    });

    //删除公司
    $('#id_com_list').dblclick(function () {
        $('#id_com_list option').each(function () {
            if(this.selected == true){
                $('#id_company_form').append(this);
            }
        });

        if($('#id_company_form option').length == 0){
            $('.selector-chooseall').addClass('disabled')
        }else {
            $('.selector-chooseall').removeClass('disabled')
        }

        if($('#id_com_list option').length == 0){
            $('.selector-clearall').addClass('disabled')
        }else {
            $('.selector-clearall').removeClass('disabled')
        }
    });

    //全选添加
    $('.selector-chooseall').click(function () {
        $('#id_company_form option').each(function () {
            $('#id_com_list').append(this);
        });

        //将所有公司设置为选中状态
        var opts = document.getElementById("id_com_list").options;
        for (var i = 0; i < opts.length; i++){
            opts[i].selected = true;
        }

        $('.selector-chooseall').addClass('disabled');
        $('.selector-clearall').removeClass('disabled')
    });

    //全选删除
    $('.selector-clearall').click(function () {
        $('#id_com_list option').each(function () {
            $('#id_company_form').append(this);
        });

        $('.selector-clearall').addClass('disabled');
        $('.selector-chooseall').removeClass('disabled')
    });

    //搜索框搜索公司
    var inputBtn = document.getElementById("id_company_input");
    var opts = document.getElementById("id_company_form").options;
    inputBtn.onkeyup = search;
    function search() {
        var inputCont = inputBtn.value;    //string
        for (var i = 0; i < opts.length; i++) {
            var optCont = opts[i].innerHTML;   //string
            var macthStr = optCont.match(inputCont);
            if (inputCont != 0) {   //为什么加这个判断呢?不加的话,按Tab键(但是用鼠标点击则不会显示),输入框就算没有输入内容,隐藏的opt标签也会显示
                if (macthStr) {
                    opts[i].style.display = "block";
                } else {
                    opts[i].style.display = "none";
                }
            }else {
                opts[i].style.display = "block";
            }
        }
    }
四、在后台adminx中保存添加的数据

在该页面对应的类中,重写保存方法

from xadmin.views.base import filter_hook
class XXXAdmin(object):
    list_display = ['']
    add_form_template = 'xxx.html'

    @filter_hook
    def save_models(self):
        req_data = dict(self.request.POST)
        com_list = req_data.get('com_list')  # 取到选择的公司列表
        update_sql = req_data.get('update_sql')  # 取到要对这些公司操作/对应的内容
        if com_list and update_sql:
            保存到你要保存表中
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值