Django- 6 -学校后台管理系统-老师管理(模态对话框元素移动)

html中列出所有老师

定制urls

urlpatterns = [
    path("teacher.html/",views.teacher),
]

编辑views

@auth
def teacher(request):
    from django.utils.safestring import mark_safe
    if request.method == "GET":
        current_page = request.GET.get("page",1)
        username = request.session.get("username")
        db_account = models.Teacher.objects.all().count()
        from utils.pagenation import pagenation
        obj = pagenation(db_account=db_account,current_page=int(current_page),redirect_url="/classes/teacher.html",rows_of_page=10,pages_num=10)
        teacher_list = models.Teacher.objects.all()[obj.page_start : obj.page_end]
        return render(request, "teacher.html",{"username":username,"teacher_list":teacher_list,"page_list":mark_safe(obj.page_html())})

编辑html

{% extends "base.html" %}
{% block title %}
{% endblock %}


{% block css %}
{% endblock %}

{% block content %}
<h1>老师管理</h1>
<table border="1" style="border-collapse: collapse;">
    <thead>
        <tr>
            <th>序号</th>
            <th>名字</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        {% for item in teacher_list %}
        <tr>
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>
            <td> <input type="button" value="编辑" class="button_edit"> | <input type="button" value="删除" class="button_delete"> </td>
        </tr>
        {% endfor %}
    </tbody>
</table>


<div class="page_turnning">
    {{ page_list }}
</div>


{% endblock %}


{% block js %}
    <script>
        $(function (){
            $('#left_menu_teacher').addClass("active");
        })
    </script>

{% endblock %}

展示

在这里插入图片描述

一个老师多教一个班

表结构

在这里插入图片描述

分析

一个老师可以教多个班,一个班也可以由多个老师上课所以需要使用Teacher表里面的many-to-many的字段查询一下这个老师教的班级
使用teacher表的many-to-many字段,就是cls字段,出来就是一个子queryset对象,所以可以再次循环子字段
后端代码不变,仅修改下前端HTML代码即可

在这里插入图片描述

修改html代码

<h1>老师管理</h1>
<table border="1" style="border-collapse: collapse;">
    <thead>
        <tr>
            <th>序号</th>
            <th>名字</th>
            <th>代课班级</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        {% for item in teacher_list %}
        <tr>
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>
            <td>
                {% for c in item.cls.all %}
                    <span class="class_tag",nid="{{ c.id }}">{{ c.caption }}</span>
                {% endfor %}
            </td>
            <td> <input type="button" value="编辑" class="button_edit"> | <input type="button" value="删除" class="button_delete"> </td>
        </tr>
        {% endfor %}
    </tbody>
</table>

查看效果

在这里插入图片描述

标记颜色

列出老师和教的所有班级

{% block css %}
<style>
    .class_tag{
        background-color: gray;
        color: white;
        padding: 5px;
        padding-right: 30px;
        border: 2px solid black;
        display: inline-block;
        border-radius: 25px;
        cursor: pointer;
    }
</style>
{% endblock %}

cursor:pointer ; 在鼠标放上去的时候,会变成一只小手
加个pointer这样鼠标放上去的时候就变成小手了

展示效果

在这里插入图片描述

删除

缺点:这里需要执行8次读库

第二种实现思路(一次读库的思路)

如果后端传了个字典,那前端也可以进行for循环

FBV修改

@auth
def teacher(request):
    from django.utils.safestring import mark_safe
    if request.method == "GET":
        current_page = request.GET.get("page",1)
        username = request.session.get("username")
        db_account = models.Teacher.objects.all().count()
        from utils.pagenation import pagenation
        obj = pagenation(db_account=db_account,current_page=int(current_page),redirect_url="/classes/teacher.html",rows_of_page=10,pages_num=10)
        teacher_list = models.Teacher.objects.filter(id__in=models.Teacher.objects.all()[obj.page_start: obj.page_end]).values("id", "name", "cls__id", "cls__caption")####注意此行,这行即对数据进行了分片,还进行了字典化处理

        #print(teacher_list)

        for i in teacher_list:
            print(i["id"],i["name"],i["cls__id"],i["cls__caption"])
        result = {}

        for t in teacher_list:
            if t["id"] not in result:
                if t["cls__id"]:#去掉None
                    result[t["id"]] = {
                        "id":t["id"],
                        "name":t["name"],
                        "cls_list":[{
                            "id":t["cls__id"],
                            "caption":t["cls__caption"],
                        }]
                    }
                else:
                    result[t["id"]] = {
                        "id": t["id"],
                        "name": t["name"],
                    }


            else:
                if t["cls__id"]:#去掉None
                    result[t["id"]]["cls_list"].append({
                        "id": t["cls__id"],
                        "caption": t["cls__caption"],
                    })
        print(result)


        return render(request, "teacher.html",{"username":username,"teacher_list":result,"page_list":mark_safe(obj.page_html())})


html修改

<table border="1" style="border-collapse: collapse;">
    <thead>
        <tr>
            <th>序号</th>
            <th>名字</th>
            <th>代课班级</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        {% for item in teacher_list.values %}
        <tr>
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>
            <td>
                {% for c in item.cls_list %}
                 <span class="class_tag",nid="{{ c.id }}">{{ c.caption }}</span>
                {% endfor %}
            </td>
            <td> <input type="button" value="编辑" class="button_edit"> | <input type="button" value="删除" class="button_delete"> </td>
        </tr>
        {% endfor %}
    </tbody>
</table>

展示

在这里插入图片描述

{
    1: {
        'id': 1,
        'name': 'teacher1',
        'cls_list': [
            {
                'id': 1,
                'caption': 'Python一班'
            },
            {
                'id': 2,
                'caption': 'Python二班'
            },
            {
                'id': 3,
                'caption': 'Python一班'
            },
            {
                'id': 4,
                'caption': 'Python二班'
            }
        ]
    },
    2: {
        'id': 2,
        'name': 'teacher2',
        'cls_list': [
            {
                'id': 1,
                'caption': 'Python一班'
            },
            {
                'id': 2,
                'caption': 'Python二班'
            },
            {
                'id': 3,
                'caption': 'Python一班'
            }
        ]
    },
    3: {
        'id': 3,
        'name': 'teacher3',
        'cls_list': [
            {
                'id': 1,
                'caption': 'Python一班'
            },
            {
                'id': 2,
                'caption': 'Python二班'
            }
        ]
    },
    4: {
        'id': 4,
        'name': 'teacher4',
        'cls_list': [
            {
                'id': 3,
                'caption': 'Python一班'
            }
        ]
    },
    5: {
        'id': 5,
        'name': 'teacher5',
        'cls_list': [
            {
                'id': 4,
                'caption': 'Python二班'
            }
        ]
    },
    6: {
        'id': 6,
        'name': 'teacher6',
        'cls_list': [
            {
                'id': 3,
                'caption': 'Python一班'
            }
        ]
    },
    7: {
        'id': 7,
        'name': 'teacher7',
        'cls_list': [
            {
                'id': 2,
                'caption': 'Python二班'
            }
        ]
    },
    8: {
        'id': 8,
        'name': 'teacher8',
        'cls_list': [
            {
                'id': 8,
                'caption': 'Python五班'
            }
        ]
    },
    9: {
        'id': 9,
        'name': 'teacher9',
        'cls_list': [
            {
                'id': 3,
                'caption': 'Python一班'
            },
            {
                'id': 8,
                'caption': 'Python五班'
            }
        ]
    },
    10: {
        'id': 10,
        'name': 'teacher1',
        'cls_list': [
            {
                'id': 3,
                'caption': 'Python一班'
            }
        ]
    },
    990: {
        'id': 990,
        'name': 'teacher11'
    },
    991: {
        'id': 991,
        'name': 'teacher11'
    },
    992: {
        'id': 992,
        'name': 'teacher11'
    },
    993: {
        'id': 993,
        'name': 'teacher11'
    },
    994: {
        'id': 994,
        'name': 'teacher11'
    },
    995: {
        'id': 995,
        'name': 'teacher11'
    },
    996: {
        'id': 996,
        'name': 'teacher11'
    },
    997: {
        'id': 997,
        'name': 'teacher11'
    },
    998: {
        'id': 998,
        'name': 'teacher11'
    },
    999: {
        'id': 999,
        'name': 'teacher11'
    },
    1000: {
        'id': 1000,
        'name': 'teacher11'
    },
    1001: {
        'id': 1001,
        'name': 'teacher11'
    },
    1002: {
        'id': 1002,
        'name': 'teacher11'
    },
    1003: {
        'id': 1003,
        'name': 'teacher11'
    }
}

添加老师(ajax提交)

需求分析:点击添加老师按钮需要弹出一个模态对话框,模态对话框里面需要有一个选择的框来可以选项这位老师所代理的班级,所以这里在点击添加按钮时就要去get到所有的班级信息,通过前端选择后然后通过ajax的POST方式提交到后台后进行数据库添加,添加成功后返回给前端页面。

html

{% extends "base.html" %}
{% block title %}
{% endblock %}


{% block css %}
<style>
    .class_tag{
        background-color: gray;
        color: white;
        padding: 5px;
        padding-right: 30px;
        border: 2px solid black;
        display: inline-block;
        border-radius: 25px;
        cursor: pointer;
    }
    .add_button{
        background-color: #84a42b;
        color: white;
        border: 1px solid;
        position: relative;
        display: inline-block;
        padding: 8px;
        border-radius: 10px;
        box-shadow: 1px 1px white ;
    }
</style>
{% endblock %}

{% block content %}
<h1>老师管理</h1>
<div class="add_button">
    <a id="add_teacher" >添加</a>
</div>



<table border="1" style="border-collapse: collapse;">
    <thead>
        <tr>
            <th>序号</th>
            <th>名字</th>
            <th>代课班级</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        {% for item in teacher_list.values %}
        <tr>
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>
            <td>
                {% for c in item.cls_list %}
                 <span class="class_tag",nid="{{ c.id }}">{{ c.caption }}</span>
                {% endfor %}
            </td>
            <td> <input type="button" value="编辑" class="button_edit"> | <input type="button" value="删除" class="button_delete"> </td>
        </tr>
        {% endfor %}
    </tbody>
</table>


<div class="page_turnning">
    {{ page_list }}
</div>


<div class="modal hide">
    <form action="/classes/add_teacher.html/" method="post">
        {% csrf_token %}
        <div>名字:
            <input class="classes_input" type="text" placeholder="此处输入老师名字" name="name">
        </div>
        <div>用户名:
            <input class="classes_input" type="text" placeholder="此处输入老师登陆系统的用户名" name="username">
        </div>
        <div>密码:
            <input class="classes_input" type="text" placeholder="此处输入老师初始密码" name="password">
        </div>
        <div>所代班级:
            <select id="select_cls" name="cls" multiple="multiple" style="width: 250px; height: 250px">



            </select>
        </div>

        <input id="id_modal_cancel" class="classes_cancel" type="button" value="取消">
        <input class="classes_submit" id="modal_ajax_submit" type="button" value="确定">
    </form>

</div>
<div class="shade hide"></div>

{% endblock %}


{% block js %}
    <script>
        $(function (){
            $('#left_menu_teacher').addClass("active");
            addTeacher()
            CancelAdd()
            SubmitAdd()
        })
        function addTeacher(){
            $("#add_teacher").click(function (){
                $(".modal,.shade").removeClass("hide");
                $.ajax({
                    url: "/classes/add_teacher.html/",
                    type: "GET",
                    dataType: "JSON",
                    success:function (rep){
                        $.each(rep,function (key,value){
                            // <option value="{{ row.id }}">{{ row.caption }}</option>
                            var op = document.createElement("option");
                            op.value = key;
                            op.innerHTML = value;
                            $("#select_cls").append(op);
                        })

                     }
                })
            })
        }

        function CancelAdd(){
            $("#id_modal_cancel").click(function (){
                $(".modal,.shade").addClass("hide")
            })
        }
        function SubmitAdd(){

            $(".classes_submit").click(function (){
                var name = document.getElementsByName("name")[0].value;
                var username = document.getElementsByName("username")[0].value;
                var password = document.getElementsByName("password")[0].value;
                //var select_id = document.getElementById("select_cls");
                var cls = $("#select_cls").val();

                $.ajax({
                    url: "/classes/add_teacher.html/",
                    method:"POST",
                    headers: {"X-CSRFToken": $.cookie("csrftoken")},//注意ajax添加csrf_token的方法
                    data:{"name":name,"username":username,"password":password,"cls":cls},
                    dataType: "JSON",
                    success: function (rep){
                        if( rep.status ){
                            alert("添加成功");
                            $(".modal,.shade").addClass("hide")//
                        }
                        else{
                            alert("添加失败");
                        }
                    }
                })
            })

        }

    </script>

{% endblock %}

views

@auth
def add_teacher(request):
    if request.method == "GET":
        #cls = models.Classes.objects.value("id","caption")
        cls = models.Classes.objects.all().values()
        #response_data = {"id":cls.id,"name":cls.caption}
        response_data = {}
        for i in cls:
            response_data[i["id"]] = i["caption"]
        return HttpResponse(json.dumps(response_data))
    if request.method == "POST":
        data = request.POST
        obj = models.Teacher.objects.create(name=data.get("name"),password=data.get("password"),username=data.get("username"))
        obj.cls.add(*data.getlist("cls[]"))
        if obj:
            response_data = {"status": True,"Message":""}
        else:
            response_data = {"status": False, "Message": ""}
        return HttpResponse(json.dumps(response_data))

修改老师信息

分析,编辑老师,首先要知道编辑哪个老师,在前面添加老师或者获取老师的时候是有老师的id的,这样的话,点击编辑的时候,需要告诉后端我要编辑哪个老师,这里其实有两个办法,一是直接通过ajax或者直接跳转网页post方式告知后端。另外一种方式是直接将老师的id放到html路径中。
二是,编辑的时候,无论是打开新的页面还是ajax都是需要获取到老师现在的信息的,如所代课的班级都需要显示出来。
三是,既然是编辑老师,那有可能需要增加代课的班级,有可能需要删除所代的班级,所以需要将所有的班级都显示出来传过去。
四是,如果是已经代的班级,要么就已经是选中的状态,要么就是已经代的班级在一个框中,没有代的班级在另外一个框中

一、点击编辑按钮获取到编辑按钮老师的id

function EditTeacher(){
            $(".button_edit").click(function (){
                $(".shade,.modal").removeClass("hide");
                console.log("test")
            })
        }
<td> <input nid="{{ item.id }}" type="button" value="编辑" class="button_edit"> | <input type="button" value="删除" class="button_delete"> </td>
        function EditTeacher(){
            $(".button_edit").click(function (){
                $(".shade,.modal").removeClass("hide");
                var id = $(this).attr("nid")//获取当前点击行的html标签中的nid,这样就拿到了当前行的id
                
            })
        }

二、将获取到id的方式发送到后端

        function EditTeacher(){
            $(".button_edit").click(function (){
                $(".shade,.modal").removeClass("hide");
                var id = $(this).attr("nid");//获取当前点击行的html标签中的nid,这样就拿到了当前行的id
                $.ajax({
                    url:"/classes/edit_teacher.html",
                    method: "GET",
                    data:{"nid":id},
                    dataType: "text",
                    success : function (rep){
                        console.log("success");
                    }
                })

            })
        }
@auth
def edit_teacher(request):
    if request.method == "GET":
        nid = request.GET.get("nid")
        print(nid)
        return HttpResponse("OK")

三、后端拿到老师ID后取出所有的已经代课了的班级

@auth
@auth
def edit_teacher(request):
    if request.method == "GET":
        nid = request.GET.get("nid")
        #cls_already = models.Teacher.objects.filter(id=nid)#返回一个query_set
        cls_already = models.Teacher.objects.get(id=nid)#返回一个对象
        print(cls_already.cls.all())#使用many-to-many来查询该老师所带的班级
        print(cls_already.cls.values())#使用many-to-many来查询该老师所带的班级
        print(cls_already.cls.values_list())#使用many-to-many来查询该老师所带的班级
        """
        <QuerySet [<Classes: Python一班>, <Classes: Python二班>, <Classes: Python一班>, <Classes: Python二班>]>
        <QuerySet [{'id': 1, 'caption': 'Python一班'}, {'id': 2, 'caption': 'Python二班'}, {'id': 3, 'caption': 'Python一班'}, {'id': 4, 'caption': 'Python二班'}]>
        <QuerySet [(1, 'Python一班'), (2, 'Python二班'), (3, 'Python一班'), (4, 'Python二班')]>

        """
        return HttpResponse("OK")

四、再取出所有还没有代课的班级

@auth
def edit_teacher(request):
    if request.method == "GET":
        nid = request.GET.get("nid")
        #cls_already = models.Teacher.objects.filter(id=nid)#返回一个query_set
        cls_already = models.Teacher.objects.get(id=nid)#返回一个对象
        # print(cls_already.cls.all())#使用many-to-many来查询该老师所带的班级
        # print(cls_already.cls.values())#使用many-to-many来查询该老师所带的班级
        # print(cls_already.cls.values_list())#使用many-to-many来查询该老师所带的班级
        # print(cls_already.cls.all().values_list("id"))#使用many-to-many来查询该老师所带的班级
        """
        <QuerySet [<Classes: Python一班>, <Classes: Python二班>, <Classes: Python一班>, <Classes: Python二班>]>
        <QuerySet [{'id': 1, 'caption': 'Python一班'}, {'id': 2, 'caption': 'Python二班'}, {'id': 3, 'caption': 'Python一班'}, {'id': 4, 'caption': 'Python二班'}]>
        <QuerySet [(1, 'Python一班'), (2, 'Python二班'), (3, 'Python一班'), (4, 'Python二班')]>

        """
        cls_already_id = list(zip(*cls_already.cls.values_list()))[0]#zip是一个内置函数,用于将一个元组的第一列信息放置到一个元组中,将第二个元素也放置到一个元组中,然后整个放置到列表
        #获取到了老师所代课班级的所有ID了
        cls_include = models.Classes.objects.filter(id__in = cls_already_id)
        cls_exclude = models.Classes.objects.exclude(id__in = cls_already_id)
        print(cls_include)
        print(cls_exclude)
        """
        <QuerySet [<Classes: Python一班>, <Classes: Python二班>, <Classes: Python一班>, <Classes: Python二班>]>
        <QuerySet [<Classes: 在>, <Classes: Python三班>, <Classes: Python四班>, <Classes: Python五班>, <Classes: Python六班>, <Classes: Python七班>, <Classes: Python七 
班>, <Classes: Python七班>, <Classes: Python七班>, <Classes: Python七班>, <Classes: Python七班>]>

        """
        return HttpResponse("OK")

营造出传递到前端的数据结构

{
    'include': [
        {
            'id': 1,
            'caption': 'Python一班'
        },
        {
            'id': 2,
            'caption': 'Python二班'
        },
        {
            'id': 3,
            'caption': 'Python一班'
        },
        {
            'id': 4,
            'caption': 'Python二班'
        }
    ],
    'exclude': [
        {
            'id': 5,
            'caption': '在'
        },
        {
            'id': 6,
            'caption': 'Python三班'
        },
        {
            'id': 7,
            'caption': 'Python四班'
        },
        {
            'id': 8,
            'caption': 'Python五班'
        },
        {
            'id': 9,
            'caption': 'Python六班'
        },
        {
            'id': 10,
            'caption': 'Python七班'
        },
        {
            'id': 11,
            'caption': 'Python七班'
        },
        {
            'id': 12,
            'caption': 'Python七班'
        },
        {
            'id': 13,
            'caption': 'Python七班'
        },
        {
            'id': 14,
            'caption': 'Python七班'
        },
        {
            'id': 15,
            'caption': 'Python七班'
        }
    ]
}

五、将已经代的和没有代课的班级都发送到前端进行展示

    .edit_teacher_modal{
            position: fixed;
            top:20%;
            left: 50%;
            width: 700px;
            height: 400px;
            background-color: white;
            margin-top -250px;
            margin-left: -250px;
            z-index: 100;

<div class="edit_teacher_modal hide">
    <form action="/classes/add_teacher.html/" method="post">
        {% csrf_token %}
        <div>名字:
            <input class="classes_input" type="text" placeholder="此处输入老师名字" name="name">
        </div>
        <div style="display: inline-block">所代班级:
            <select id="select_cls" name="cls" multiple="multiple" style="width: 250px; height: 250px">
                <div>可按住“ctrl”键进行多选</div>
            </select>
        </div>

        <div style="display: inline-block">其它班级:
            <select id="select_cls" name="cls" multiple="multiple" style="width: 250px; height: 250px">
                <div>可按住“ctrl”键进行多选</div>
            </select>
        </div>
        <div>
            <input id="id_modal_cancel_edit_teacher" class="classes_cancel" type="button" value="取消">
            <input class="classes_submit" id="modal_ajax_submit" type="button" value="确定">
        </div>


    </form>

</div>         
@auth
def edit_teacher(request):
    if request.method == "GET":
        nid = request.GET.get("nid")
        print(nid)
        #cls_already = models.Teacher.objects.filter(id=nid)#返回一个query_set
        cls_already = models.Teacher.objects.get(id=nid)#返回一个对象
        # print(cls_already.cls.all())#使用many-to-many来查询该老师所带的班级
        # print(cls_already.cls.values())#使用many-to-many来查询该老师所带的班级
        # print(cls_already.cls.values_list())#使用many-to-many来查询该老师所带的班级
        # print(cls_already.cls.all().values_list("id"))#使用many-to-many来查询该老师所带的班级
        """
        <QuerySet [<Classes: Python一班>, <Classes: Python二班>, <Classes: Python一班>, <Classes: Python二班>]>
        <QuerySet [{'id': 1, 'caption': 'Python一班'}, {'id': 2, 'caption': 'Python二班'}, {'id': 3, 'caption': 'Python一班'}, {'id': 4, 'caption': 'Python二班'}]>
        <QuerySet [(1, 'Python一班'), (2, 'Python二班'), (3, 'Python一班'), (4, 'Python二班')]>

        """
        cls_already_id = list(zip(*cls_already.cls.values_list()))[0]#zip是一个内置函数,用于将一个元组的第一列信息放置到一个元组中,将第二个元素也放置到一个元组中,然后整个放置到列表
        #获取到了老师所代课班级的所有ID了
        cls_include = models.Classes.objects.filter(id__in = cls_already_id).values()
        cls_exclude = models.Classes.objects.exclude(id__in = cls_already_id).values()

        cls_dict = {"include":[],"exclude":[]}
        for i in cls_include:
            cls_dict["include"].append(i)
        for i in cls_exclude:
            cls_dict["exclude"].append(i)
        return HttpResponse(json.dumps(cls_dict))

    function EditTeacher(){
            $(".button_edit").click(function (){
                $(".shade,.edit_teacher_modal").removeClass("hide");
                var id = $(this).attr("nid");//获取当前点击行的html标签中的nid,这样就拿到了当前行的id
                $.ajax({
                    url:"/classes/edit_teacher.html",
                    method: "GET",
                    data:{"nid":id},
                    dataType: "JSON",
                    success : function (rep){
                        $.each(rep,function (key,value){
                            if (key == "include"){
                                $.each(value,function (id,caption){
                                    var op = document.createElement("option");
                                    console.log(caption);
                                    op.value = caption.id;
                                    op.innerHTML = caption.caption;
                                    op.selected = "selected";
                                    $("#edit_select_cls").append(op);
                                })

                            }
                            else {
                                $.each(value,function (id,caption){
                                    var op = document.createElement("option");
                                    console.log(caption);
                                    op.value = caption.id;
                                    op.innerHTML = caption.caption;
                                    //op.selected = "selected";
                                    $("#edit_execlude_cls").append(op);
                                })
                            }

                        })
                    }
                })

            })
        }

        function CancelEditTeacher(){
            $("#id_modal_cancel_edit_teacher").click(function (){
                $(".edit_teacher_modal,.shade").addClass("hide");
                $(".select_cls").empty();//点击取消时,需要清楚掉所有的标签,否则再次点击时会再次创建一遍标签,这样所有的选项会再多一倍
            })
        }

在这里插入图片描述
左边是此老师已经代课的班级,右边是所有没有代课的班级

六、进行编辑操作

6.1 先营造一个左右移动的按钮

<div class="edit_teacher_modal hide">
    <form action="/classes/add_teacher.html/" method="post">
......

        <div style="display: inline-block">
            <div class="right_move move">>></div>
            <div class="left_move move"><<</div>
        </div>

......
    </form>

</div>
    .move{
        background-color: #84a42b;
        color: white;
        border: 1px solid;
        position: relative;
        padding: 8px;
        border-radius: 10px;
        box-shadow: 1px 1px white ;
    }

在这里插入图片描述

搞定左往右移(减少班级)

分析:每一个班级都是一个html的标签,选中的班级,那么需要完成以下几个动作:
1、找出选中的option标签
2、将选中的标签从左边的框删除,在右边的框增加
3、最后提交都只需要提交左边的框即可。

找出选中的标签–$(“#edit_select_cls”)[0].selectedOptions
$("#edit_select_cls")[0].selectedOptions
HTMLCollection { 0: option, 1: option, 2: option
, length: 3 }
​
0: <option value="2">​
1: <option value="3">​
2: <option value="4">
​
length: 3
​
<prototype>: HTMLCollectionPrototype { item: item(), namedItem: namedItem(), length: Getter, … }
左往右移按钮绑定事件

$(“#edit_select_cls”)[0].selectedOptions[0].outerHTML.appendTo(“edit_execlude_cls”)

        function LeftTORight(){
            $(".right_move").click(function () {
                var op = $("#edit_select_cls")[0].selectedOptions;
                while (op.length>0){
                    console.log(op[0]);
                    $(op[0]).appendTo("#edit_execlude_cls");
                }
            })
        }

在这里插入图片描述

搞定右往左移(增加班级)

分析,从右往左移也是一样的情况,只需要绑定相应的标签的class即可。

        function RightTOLeft(){
            $(".left_move").click(function () {
                var op = $("#edit_execlude_cls")[0].selectedOptions;
                while (op.length>0){
                    console.log(op[0]);
                    $(op[0]).appendTo("#edit_select_cls");
                }
            })
        }

在这里插入图片描述

七、将最新的数据发送到后端

分析:现在进行左右移动后,提交时,只需要将左边的提交到后台进行后台数据库操作即可
提交数据时,需要提交老师的ID,和课程左边框内的班级ID
所以最好构建一个json数据类型,告知teacher id和cls_list
怎么拿老师的id呢?在之前点击编辑的时候就拿到了老师ID,那我们可以搞一个隐藏的input框,用户看不见,将这个id放到input框内,这时在点击确定之前,可以使用这个隐藏的input框加上selected的框来组成一个json数据结构。

7.1 搞定teacher id 信息

点击编辑后,会弹出模态对话框,,增加一个隐藏的input框式,将老师的id放进去

 {% csrf_token %}
        <div>名字:
            <input class="classes_input" type="text" placeholder="此处输入老师名字" name="name">
            <div class="teacher_info" style="display: none"></div>
        </div>

为什么要搞一个单独的div标签,因为如果页面不关闭,那么每次一点编辑都会增加一个input框,如果点击取消,再点击编辑又会多增加一个,所以为了再点击取消的时候能够将框删除,所以单独增加一个div标签,点击取消时,直接enpty掉。

       function EditTeacher(){
            $(".button_edit").click(function (){
                $(".shade,.edit_teacher_modal").removeClass("hide");
                var id = $(this).attr("nid");//获取当前点击行的html标签中的nid,这样就拿到了当前行的id

                var teacher_input = document.createElement("input")
                teacher_input.value = id
                teacher_input.className = "hide_teacher_id"//如果点击了添加老师,再点取消不清除的话,ID会重复增加,所以加一个class,在点击取消时要将此标签删除
                $(".teacher_info").append(teacher_input)

               ......
                })
        function CancelEditTeacher(){
            $("#id_modal_cancel_edit_teacher").click(function (){
                $(".teacher_info").empty();//点击取消时,需要清楚掉所有的标签,否则再次点击时会再次创建一遍标签,这样所有的选项会再多一倍
            })
        }

7.2 搞定班级列表cls_list

        function EditTeacherSubmit(){
            $(".classes_edit_submit").click(function (){
                var teacher_id = $(".hide_teacher_id").val();//直接获取老到的id
                var class_list = $("#edit_select_cls").val();
                console.log(class_list);
            })
        }

7.3 将数据发送到后端

        function EditTeacherSubmit(){
            $(".classes_edit_submit").click(function (){
                var teacher_id = $(".hide_teacher_id").val();//直接获取老到的id
                var class_list = $("#edit_select_cls").val();
                console.log(class_list);
                $.ajax({
                    url:"/classes/edit_teacher.html/",
                    method:"POST",
                    headers: {"X-CSRFToken": $.cookie("csrftoken")},//注意ajax添加csrf_token的方法
                    data:{"teacher_id":teacher_id,"cls_list":class_list},
                    dataType:"JSON",
                    success:function (reply){
                        console.log("success");
                    }
                })
            })
        }
@auth
def edit_teacher(request):
    if request.method == "GET":
    ##。。。。。。##
    elif request.method == "POST":
        reply = request.POST
        print(reply)
        return HttpResponse("OK")

后端的输出结果:

<QueryDict: {'teacher_id': ['1'], 'cls_list[]': ['1', '2', '3', '4']}>
<QueryDict: {'teacher_id': ['1'], 'cls_list[]': ['1', '2', '3', '4', '10', '12', '13']}>

八、后端进行数据库更新操作

数据库更新有几种方式
1,先将老师代课的所有班级全清空后重新添加
2,已经代课的班级不动,加上新的班级,去掉没有的班级,就是两个集合对比,原来的集合中有的,而新的集合中没有的就删除,原来的集合中没有,而新的集合中有的就增加

这里选择第二种方式

@auth
def edit_teacher(request):
    if request.method == "GET":
       ##省略


    elif request.method == "POST":
        reply = request.POST
        print("reply",reply)
        teacher_id = reply.get("teacher_id")
        # 从前端提交过来的数据中拿到老师
        teacher = models.Teacher.objects.get(id=teacher_id)
        # 拿到前端传递过来老师所代课的班级,有可能减少,有可能增加,也有可能是0
        cls_list_new = list(map(int,reply.getlist("cls_list[]")))#map函数,用于将字符型的数字转换为int类型。
        # 拿到该老师编辑前所代课的班级,有可能是0,如果是0就有可能报错,所以加上一个try,这样即使也可以继续往下走
        try:
            cls_list_old = list(list(zip(*teacher.cls.all().values_list()))[0])
        except Exception as e:
            print(e)
            cls_list_old = []

# 增加两外一个是删除的通过比较后,需要删除的列表,一个是通过比较后增加的列表
        cls_del = []
        cls_add = []
        for i in cls_list_old:
            if i in cls_list_new:
                continue
            else:
                cls_del.append(i)
        for i in cls_list_new:
            if i in cls_list_old:
                continue
                # 在列表里的就不用操作第
            else:
                cls_add.append(i)
        try:
            teacher.cls.remove(*cls_del)
            teacher.cls.add(*cls_add)
            response_data = {"status": True, "error": None, "data": None}
        except Exception as e:
            response_data = {"status": False, "error": e, "data": None}
        print(teacher,cls_list_old,cls_list_new,cls_del,cls_add)
        return HttpResponse(json.dumps(response_data))
       function EditTeacherSubmit(){
            $(".classes_edit_submit").click(function (){
                var teacher_id = $(".hide_teacher_id").val();//直接获取老到的id
                $("#edit_select_cls").children().each(function (){
                    $(this).prop("selected", true);
                })
                var class_list = $("#edit_select_cls").val();
                console.log(class_list);
                $.ajax({
                    url:"/classes/edit_teacher.html/",
                    method:"POST",
                    headers: {"X-CSRFToken": $.cookie("csrftoken")},//注意ajax添加csrf_token的方法
                    data:{"teacher_id":teacher_id,"cls_list":class_list},
                    dataType:"JSON",
                    success:function (reply){
                        console.log("success",reply);
                        if (reply.status == true){
                            alert("操作成功");
                            location.reload();
                            $(".shade,.edit_teacher_modal").addClass("hide");
                        }
                    }
                })
            })
        }

在这里插入图片描述

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值