IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Django - 3 - 班级管理后台页面 -> 正文阅读

[Python知识库]Django - 3 - 班级管理后台页面

文章目录

后台管理系统页面母板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
<!--    模板语言,后面可以替换-->
    <title>{% block title %} {% endblock %}</title>
    <style>
        /*最顶部区域导航栏的样式设置*/
        .toparea {
            height: 80px;
            width: 100%;
            background-color: beige;
            text-align: center;
            vertical-align: center;
        }
/*顶部区域,中间的欢迎语样式设置*/
        .toparea .welcom {
            position: fixed;
            left: 40%;
            top: 30px;
            font-size: 30px;
            font-style: italic;
            color: orange;
        }

        .left_menu {
            position: fixed;
            width: 200px;
            height: 100%;
            background-color: cornflowerblue;
        }
        .content_area {
            position: fixed;
            left: 200px;
            width: 100%;
            height: 100%;
            background-color: rosybrown;
        }
        .left_menu .item {
            display: block;
            padding: 5px 30px;
            font-size: 30px;
            border-bottom: solid 1px orange;
        }

        .left_menu .item:hover {
            color: orange;
            background-color: darkgrey;
        }

        .left_menu .item.active {
            background-color: chocolate;
            color: white;
        }

    </style>
<!--    留模板,后面好继承时可替换-->
    {% block css %} {% endblock %}
</head>
<body>
<div class="toparea">
    <div class="welcom">
        欢迎使用学校后台管理系统
    </div>
    <div class="username" style="position: fixed;right:10px;top:40px ;text-align: center;vertical-align: middle " >用户名: {{ username }}
        <a  href="/classes/logout.html">
            注销登陆
        </a>
    </div>
</div>
<div class="left_menu">
    <a id="left_menu_classes" class="item" href="/classes/classes.html">班级管理</a>
    <a id="left_menu_teacher" class="item" href="/classes/teacher.html">老师管理</a>
    <a id="left_menu_student" class="item" href="/classes/student.html">学生管理</a>

</div>
<div class="content_area">
    {% block content %} {% endblock %}

</div>
    <script src="/static/jquery-2.1.4.min.js"></script>
    <script src="/static/jquery.cookie.js"></script>
    {% block js %} {% endblock %}
</body>
</html>

在这里插入图片描述
在这里插入图片描述
左边跟上边不动,所以做成个木板
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面是scripts

继承

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

每个子菜单的设置

<div class="left_menu">
    <a class="item" href="/classes/manage.html">班级管理</a>
    <a class="item" href="/classes/teacher.html">老师管理</a>
    <a class="item" href="/classes/student.html">学生管理</a>

</div>

添加一个href 做为链接跳转

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

学生列表

在这里插入图片描述

老师列表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

增加一个选中点击的时候变色

<div class="left_menu">
    <a id="left_menu_classes" class="item" href="/classes/classes.html">班级管理</a>
    <a id="left_menu_teacher" class="item" href="/classes/teacher.html">老师管理</a>
    <a id="left_menu_student" class="item" href="/classes/student.html">学生管理</a>

</div>

第一步:base.html中先每一个菜单添加一个ID,用于JS来获取

    <style>
        .left_menu .item:active {
            background-color: chocolate;
            color: white;
        }
    </style>

第二步:base.html中设置如果有class标签的就变成什么颜色

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

第三步:在每一个子html文件中,添加如上代码,意思是添加一个class,名字为“active”,techer,student,classes 3个子html文件都要添加

现在在哪个菜单下,哪个菜单就是单独的颜色。

动态的选中现在在用的菜单(现在在哪个菜单上哪个菜单就深色)

模板已经引用jquery所以,这里不用再引入了
在这里插入图片描述

如果点了别的页面后,页面自动刷新,所以不用设置移除

设置margin为0

    <style>
				 body {
				            margin: 0;
				        }
		</style> 

内容块

目标是点击班级管理后,先显示出所有数据库里面有的班级,然后班级可以编辑,可以删除,还可以添加

班级列表

先编辑views,让能够从数据库中获取所有的表


def classes(request):
    username = request.session.get("username")
    class_list = models.Classes.objects.all()

    return render(request, "classes.html",{"username": username,"class_list":class_list})

先获取所有的班级列表

再写前端页面,可以展示这所有的班级

前端表格相关标签:

  • 表示表格,表格的所有内容需要写在
    之间。
  • 是 table row 的简称,表示表格的行。表格中有多少个 标签就表示有多少行数据。
  • 是 table datacell 的简称,表示表格的单元格,这才是真正存放表格数据的标签。单元格的数据可以是文本、图片、列表、段落、表单、水平线、表格等多种形式。
  • 是 table heading 的简称,表示表格的表头。 其实是 单元格的一种变体,本质上还是一种单元格。 一般位于第一行,充当每一列的标题。大多数的浏览器会把表头显示为粗体居中的文本。
  • 标签用于组合 HTML 表格的表头内容。
  • 元素应该与 和 元素结合起来使用,用来规定表格的各个部分(表头、主体、页脚)。通过使用这些元素,使浏览器有能力支持独立于表格表头和表格页脚的表格主体滚动。当包含多个页面的长的表格被打印时,表格的表头和页脚可被打印在包含表格数据的每张页面上。
  • 标签必须被用在以下情境中:作为 元素的子元素,出现在 元素之后,、 和 元素之前。
{% extends "base.html" %}
{% block title %}
{% endblock %}


{% block css %}
{% endblock %}

{% block content %}
<div>
    <input type="button" value="添加">
</div>
<table border="1" style="border-collapse: collapse;" >
    <caption>班级列表</caption>
    <thead>
    <tr>
        <th>编号</th>
        <th>名称</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    {% for item in class_list %}
    <tr>
        <td>{{ item.id }}</td>
        <td>{{ item.caption }}</td>
        <td><a>编辑</a> | <a>删除</a></td>
    </tr>
    {% endfor %}
    </tbody>

</table>
{% endblock %}


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

访问测试

在这里插入图片描述

head和body都要加上,不然会自动找上一级,这样容易乱

添加按钮绑定事件

为添加添加一个id

<div>
    <input id="id_add" type="button" value="添加">
</div>

绑定JS(目标是执行一个模态对话框)

    <script>
        $(function (){
            $("#left_menu_classes").addClass("active");
        })
        function bindAddEvent(){
            $("#id_add").click(function (
                #这里写上绑定什么功能
            ))
        }
    </script>

写在上面是因为页面一打开就可以准备这个事件,然后如果一点击就应该给出一个页面框框。

写模态对话框(很多位置需要用到模态对话框,所以写在母板)

所谓模态对话框就是在其没有被关闭之前,用户不能与同一个应用程序下的其他窗口进行交互,直到该对话框关闭,比如记事本的另存为窗口。对于非模态对话框,当被打开时,用户既可选择和该对话框进行交互,也可以选择同应用程序的其他窗口交互,比如记事本上帮助内的反馈窗口。

好多地方需要使用到这个模态对话框,所以写在公共位置。所以写在母板

母板中添加3个样式
    <style>
        .hide {
            display: none;
        }

        .modal{
            position: fixed;
            top:50%;
            left: 50%;
            width: 500px;
            height: 400px;
            background-color: white;
            margin-top -250px;
            margin-left: -250px;
            z-index: 100;
        }


        .shade{
            position: fixed;
            top:0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: black;
            opacity: 0.5;
            z-index: 99;
        }

      </style>

z-index 属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。
注释:元素可拥有负的 z-index 属性值。
注释:Z-index 仅能在定位元素上奏效(例如 position:absolute;)!

子html中body中添加两个div框

<div class="modal hide"></div>
<div class="shade hide"></div>
回到script中,添加相关绑定的操作
    <script>
        $(function (){
            $("#left_menu_classes").addClass("active");
            bindAddEvent()
        })
        function bindAddEvent(){
            $("#id_add").click(function () {
                $(".modal,.shade").removeClass("hide");
            })
        }
    </script>
点击展示

在这里插入图片描述

模态框中添加几个输入框
<div class="modal hide">
    <input class="classes_input" type="text" placeholder="此处输入班级名称">
    <input class="classes_submit" type="button" value="确定">
    <input class="classes_cancel" type="button" value="取消">
</div>

placeholder 的功能就是在输入框内输入一段文字
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

    <script>
        $(function (){
            $("#left_menu_classes").addClass("active");
            bindCancelModal()
        })

        function bindCancelModal(){
            $("#id_modal_cancel").click(function (){
                $(".modal,.shade").addClass("hide");
            })
        }
    </script>

在这里插入图片描述

删除的模态对话框

在这里插入图片描述

删除按钮绑定操作

在这里插入图片描述
点击删除按钮后,对应的条目应该删掉,而这个操作需要使用模态对话框来提示是否确认删除,如果点击确认的话,则将需要删除的数据的ID,POST到后台进行数据库删除。
所以第一步,先搞定点击删除后弹出一个框来

第一步:点击删除弹框

删除按钮绑定事件

    {% for item in class_list %}
    <tr>
        <td>{{ item.id }}</td>
        <td>{{ item.caption }}</td>
        <td><a id="button_edit">编辑</a> | <a id="button_delete">删除</a></td>
    </tr>
    {% endfor %}

添加一个模态对话框

<div class="modal hide">
    <input class="classes_input" type="text" placeholder="此处输入班级名称">
    <input class="classes_submit" type="button" value="确定">
    <td><a class="button_edit">编辑</a> | <a class="button_delete">删除</a></td>
</div>

<div class="shade hide"></div>
<div class="remove hide">
    <input class="classes_submit" type="button" value="确定">
    <input id="id_remove_cancel" class="classes_cancel" type="button" value="取消">
</div>

如上图,增加了一个class=“remove hide” 的div 标签,里面添加两个按钮,删除的按钮有个ID,ID后面有用

添加remove的style

在base.html中添加

     <style>
        .remove{
            position: fixed;
            top:20%;
            left: 50%;
            width: 500px;
            height: 400px;
            background-color: coral;
            margin-top -250px;
            margin-left: -250px;
            z-index: 100;
        }
     </style>

点击之后只需要显示这两个即可。
写remove样式

    <script>
        $(function (){
            $("#left_menu_classes").addClass("active");
            bindAddEvent()
            bindCancelModal()
            bindDeleteEvent()
        })

        function bindDeleteEvent(){
            $("td .button_delete").click(function () {
                $(".remove,.shade").removeClass("hide")
            })
        }
    </script>

查看点击效果在这里插入图片描述

第二步 将取消按钮加上去掉模态对话框

    <script>
        $(function (){
            $("#left_menu_classes").addClass("active");
            bindAddEvent()
            bindCancelModal()
            bindDeleteEvent()
        })
        function bindAddEvent(){
            $("#id_add").click(function () {
                $(".modal,.shade").removeClass("hide");
            })
        }
        function bindCancelModal(){
            $("#id_modal_cancel,#id_remove_cancel").click(function (){
                $(".modal,.shade,.remove").addClass("hide");
            })
        }

        function bindDeleteEvent(){
            $("td .button_delete").click(function () {
                $(".remove,.shade").removeClass("hide");
            })
        }
    </script>

function bindCancelModal() 中添加了#id_remove_cancel,也添加了function bindDeleteEvent() 的函数

添加按钮,使用Form 添加数据

<div class="modal hide">
    <form action="/classes/classes.html/" method="post">
        {% csrf_token %}
        <input class="classes_input" type="text" placeholder="此处输入班级名称" name="caption">
        <input class="classes_submit" type="submit" value="确定">
        <input id="id_modal_cancel" class="classes_cancel" type="button" value="取消">
    </form>

</div>

第一种方式,直接提交的数据写库,然后重定向刷新页面

@auth
def classes(request):
    if request.method == "GET":
        username = request.session.get("username")
        class_list = models.Classes.objects.all()
        # models.Classes.objects.create(caption = "Python一班")
        # models.Classes.objects.create(caption = "Python二班")

        return render(request, "classes.html",{"username": username,"class_list":class_list})
    elif request.method == "POST":
        caption = request.POST.get("caption")
        models.Classes.objects.create(caption=caption)
        return redirect("/classes/classes.html")

操作测试

在这里插入图片描述
在这里插入图片描述

操作完了后,刷新新的页面,要么get一遍,要么redirect

第二种方式 模态对话框的时候建议使用AJAX的方式提交,不使用FORM

绑定事件
接下来要发ajax数据了,但是在发送之差需要先获取ajax的数据。

第一步,修改html中,添加一个ajax的按钮

<div class="modal hide">
    <form action="/classes/classes.html/" method="post">
        {% csrf_token %}
        <input class="classes_input" type="text" placeholder="此处输入班级名称" name="caption">
<!--        <input class="classes_submit" type="submit" value="确定">-->
        <input id="id_modal_cancel" class="classes_cancel" type="button" value="取消">
        <input class="classes_submit" id="modal_ajax_submit" type="button" value="确定">

    </form>

</div>

注意,使用ajax提交,form中就不是submit了,普通的button,动作在ajax中进行定义

success就是用户返回的数据了
ajax与form有不同,form有跳转

第二步:修改views方法,处理ajax的数据

@auth
def classes(request):
    if request.method == "GET":
        username = request.session.get("username")
        class_list = models.Classes.objects.all()
        return render(request, "classes.html",{"username": username,"class_list":class_list})
    elif request.method == "POST":
        import json
        response_data = {"status": True, "error": None,"data": None}
        caption = request.POST.get("caption",None)
        if caption:
            models.Classes.objects.create(caption=caption)
        else:
            response_data["status"] = False
            response_data["error"] = "课程名称不能为空"
        return HttpResponse(json.dumps(response_data))

第三步 添加JS绑定动作,使用AJAX进行提交

        function bindSubmitModal(){
            $("#modal_ajax_submit").click(function (){
                var value = $('.modal input[name="caption"]').val()
                $.ajax({
                    url: "/classes/classes.html/",
                    type: "POST",
                    headers: {"X-CSRFToken": $.cookie("csrftoken")},//注意ajax添加csrf_token的方法
                    dataType:"JSON",
                    data: {caption: value},
                    success: function (data){
                        // data = JSON.parse(data)  //如果传过来的不是json的数据,需要进行序列化
                        if (!data.status){
                            alert(data.error);
                        }else {
                            location.reload()
                        }
                    },
                    })
            })
        }

注意csrf_token的添加方法

第四步 添加成功测试

在这里插入图片描述
在这里插入图片描述

第五步 添加失败的测试(填入数据为空的时候)

在这里插入图片描述

两种方式,一种是type直接定义返回为jason,那就不用json.parse了

添加成功(AJAX提交成功)后的处理方式

第一种方式,直接局部刷新,这样就相当于重新从数据库拉取了一次数据。

成功后直接关闭—两种处理方式,第一种是location.reload() 直接将这个位置刷新一下,不需要整个页面刷新。

第二种方式,将添加的值直接显示在前端两面的最后

这句代码表示“当前页面刷新一下。”这是一种解决方式,还有一种方式,不刷新,将数据放到表后面。

第一步 修改html,将

    <script>
        $(function (){
            $("#left_menu_classes").addClass("active");
            bindAddEvent()
            bindCancelModal()
            bindDeleteEvent()
            bindSubmitModal()
        })


        function bindSubmitModal(){
            $("#modal_ajax_submit").click(function (){
                var value = $('.modal input[name="caption"]').val()
                $.ajax({
                    url: "/classes/classes.html/",
                    type: "POST",
                    headers: {"X-CSRFToken": $.cookie("csrftoken")},//注意ajax添加csrf_token的方法
                    dataType:"JSON",
                    data: {caption: value},
                    success: function (rep){
                        // data = JSON.parse(data)
                        if (!rep.status){
                            alert(rep.error);
                        }else {
                            //location.reload()
                            // <tr>
                            //     <td>{{item.id}}</td>
                            //     <td>{{item.caption}}</td>
                            //     <!--        <td><a class="button_edit">编辑</a> | <a  class="button_delete">删除</a></td>-->
                            //     <td><input type="button" value="编辑" className="button_edit"> | <input type="button"
                            //                                                                           value="删除"
                            //                                                                           className="button_delete">
                            //     </td>
                            // </tr>
                            var tr = document.createElement("tr"); //创建一个tr标签
                            var td1 = document.createElement("td"); // 创建一个td标签
                            var td2 = document.createElement("td");
                            var td3 = document.createElement("td");
                            var input1 = document.createElement("input"); //创建一个input标签
                            var input2 = document.createElement("input");
                            td1.innerHTML= rep.data.id; //rep是ajax提交数据后后端返回给前端的数字,是后端定义的一个字典response_data = {"status": True, "error": None,"data": None},因为里面包含了data变量,所以这里最好就不要再有data了。
                            td2.innerHTML= rep.data.caption; //rep是ajax提交数据后后端返回给前端的数字,是后端定义的一个字典response_data = {"status": True, "error": None,"data": None},因为里面包含了data变量,所以这里最好就不要再有data了。
                            input1.value = "编辑";//编辑input标签里面的value属性
                            input1.className = "button_edit";//编辑input标签里面的class属性
                            input1.type = "button";

                            input2.value = "删除";
                            input2.className = "button_delete";
                            input2.type = "button";
                            td3.innerText = " | ";  //td3标签里添加文本数据“|”
                            $(td3).prepend(input1); //在“|”文本数据前加上input1标签
                            $(td3).append(input2); //在“|”文本数据后添加上input2标签
                            $(tr).append(td1);//tr标签内嵌 td1标签,下同
                            $(tr).append(td2);
                            $(tr).append(td3);
                            $("table tbody").append(tr); //将整个tr标签添加到 table  tbody标签后
                            $(".modal,.shade").addClass("hide"); //点击添加后即删除模态对话框
                        }
                    },
                    })
            })
        }
    </script>

第二步 修改views函数

def classes(request):
    if request.method == "GET":
        username = request.session.get("username")
        class_list = models.Classes.objects.all()
        # models.Classes.objects.create(caption = "Python一班")
        # models.Classes.objects.create(caption = "Python二班")

        return render(request, "classes.html",{"username": username,"class_list":class_list})
    elif request.method == "POST":
        # caption = request.POST.get("caption")
        # models.Classes.objects.create(caption=caption)
        # return redirect("/classes/classes.html")
        import json
        response_data = {"status": True, "error": None,"data": None}
        caption = request.POST.get("caption",None)
        if caption:
            obj = models.Classes.objects.create(caption=caption)
            response_data["data"] = {"id":obj.id,"caption":obj.caption}

        else:
            response_data["status"] = False
            response_data["error"] = "课程名称不能为空"
        return HttpResponse(json.dumps(response_data))
        > obj = models.Classes.objects.create(caption=caption)
        > response_data["data"] = {"id":obj.id,"caption":obj.caption}

注意这两句,
写完之后将数据追加至最后。ID和数据来自哪儿呢?
AJAX提交数据后,会写库,但是写库也是一个对象,所以会有id与caption,将这两个值返回给前端即可,这样只需要返回一个字典给前端,不需要返回整个页面,节省了网络带宽

在这里插入图片描述

在这里插入图片描述

绑定委托

因为新加入的一行数据是通过ajax的函数方法在表格后面追加的标签,数据来源于后台提供的字典数据,这个时候虽然有数据,有标签,有class等属性,但是并不是绑定动作,动作都是在页面渲染的时候绑定的,所以这个时候需要进行委托,需要将比如编辑和删除的动作委托到上层标签上,这样即使添加的数据也可以进行点击操作。

修改删除js

        function bindDeleteEvent(){
            // $("td .button_delete").click(function () {
            //     $(".remove,.shade").removeClass("hide");
            // })

            // <tbody>
            // {% for item in class_list %}
            // <tr>
            //     <td>{{item.id}}</td>
            //     <td>{{item.caption}}</td>
            //     <!--        <td><a class="button_edit">编辑</a> | <a  class="button_delete">删除</a></td>-->
            //     <td><input type="button" value="编辑" className="button_edit"> | <input type="button" value="删除"
            //                                                                           className="button_delete"></td>
            // </tr>
            // {% endfor %}
            // </tbody>
            // 如上,数据是在tbody上面加的一行tr数据,tr后面有td数据,我们需要在td的button_delete上面绑定删除的操作,这个时候绑定的上层标签就是tbody,所以将这个绑定委托到tbod标签上

            $("tbody").on("click",".button_delete",function () {
                $(".remove,.shade").removeClass("hide");
            })
        }

访问测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

添加数据之跳转URL方式提交

第一步:classes.html中添加一个按钮用于点击后跳转

<div>
    <input id="id_add" type="button" value="添加">
    <a href="/classes/add_classes.html">
        <input type="button" value="跳转添加">
    </a>
</div>

第二步:新建一个add_classes.html

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


{% block css %}
{% endblock %}

{% block content %}
<h1>添加班级</h1>
<form method="post" action="/classes/add_classes.html/">
    <input name="caption" placeholder="请输入你要添加的班级" type="text">
    <input type="submit" value="提交">
    <input type="button" value="取消">
    {% csrf_token %}
    
    <a>{{ message }}</a>
</form>
{% endblock %}


{% block js %}
    <script>
        $(function (){
            $("#left_menu_classes").addClass("active"); //这里是为了即使跳转后,新的页面左侧的导航栏继续为橙色标示
        })
    </script>
{% endblock %}

第三步:urls

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

第四步 views

def add_classes(request):
    message = ""
    if request.method == "GET":
        return render(request,"add_classes.html",{"message":message})
    elif request.method == "POST":
        caption = request.POST.get("caption",None)
        if caption:
            obj = models.Classes.objects.create(caption=caption)
            return redirect("/classes/classes.html")
        else:
            message = "班级不允许为空,请重新输入"
            return render(request, "add_classes.html",{"message":message})

    else:
        return redirect("/classes/classes.html")

输入值测试

在这里插入图片描述
在这里插入图片描述

空值测试

在这里插入图片描述

两种方式对比

模态对话框使用JS较多,且包含的内容较少,如果填值较多,建议使用跳转网页的方式

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-05-18 17:35:34  更:2022-05-18 17:36:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 13:41:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码