• Python全栈之路-Django(六)


    1 Ajax发送数据

    发送数据有列表时,需要添加traditional:true

    $.ajax({
        ...
        data: {'k1':[1,2,3,4]},
        traditional:true,
        ...
    })
    

    发送数据有字典时,需JSON序列化成字符串后发送给后端

    $.ajax({
        ...
        data: {'k1':JSON.stringify({'k2':'v2','k3':'v3',...})},
        ...
    })
    

    2 Bootstrap

    目标:完善学员管理系统
    1.Bootstrap

    • 定义:一个包含CSS和JS的一个代码库
    • 我们需要了解的是:

    响应式布局:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .pg-header{
                background-color: #2aabd2;
                height: 48px;
            }
            @media (max- 900px) {
                .pg-header{
                    background-color: red;
                    height: 48px;
                }
            }
            @media (max- 700px) {
                .pg-header{
                    background-color: green;
                    height: 48px;
                }
            }
    
        </style>
    </head>
    <body>
        <div class="pg-header"></div>
    </body>
    </html>
    

    bootstrap导航条

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
    </head>
    <body>
        <nav class="navbar navbar-default">
      <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Brand</a>
        </div>
    
        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
            <li><a href="#">Link</a></li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
              <ul class="dropdown-menu">
                <li><a href="#">Action</a></li>
                <li><a href="#">Another action</a></li>
                <li><a href="#">Something else here</a></li>
                <li role="separator" class="divider"></li>
                <li><a href="#">Separated link</a></li>
                <li role="separator" class="divider"></li>
                <li><a href="#">One more separated link</a></li>
              </ul>
            </li>
          </ul>
          <form class="navbar-form navbar-left">
            <div class="form-group">
              <input type="text" class="form-control" placeholder="Search">
            </div>
            <button type="submit" class="btn btn-default">Submit</button>
          </form>
          <ul class="nav navbar-nav navbar-right">
            <li><a href="#">Link</a></li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
              <ul class="dropdown-menu">
                <li><a href="#">Action</a></li>
                <li><a href="#">Another action</a></li>
                <li><a href="#">Something else here</a></li>
                <li role="separator" class="divider"></li>
                <li><a href="#">Separated link</a></li>
              </ul>
            </li>
          </ul>
        </div><!-- /.navbar-collapse -->
      </div><!-- /.container-fluid -->
    </nav>
    </body>
    </html>
    

    3 学员管理后台布局

    Django母版

    • 母版:存放所有页面公用代码
    • 子版:继承母版并填充自定义当前页面的代码

    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^classes/', views.classes),
        url(r'^add_class/', views.add_class),
        url(r'^del_class/', views.del_class),
        url(r'^edit_class/', views.edit_class),
        url(r'^students/', views.students),
        url(r'^add_student/', views.add_student),
        url(r'^del_student/', views.del_student),
        url(r'^edit_student/', views.edit_student),
        url(r'^modal_add_class/', views.modal_add_class),
        url(r'^modal_edit_class/', views.modal_edit_class),
        url(r'^modal_add_student/', views.modal_add_student),
        url(r'^modal_edit_student/', views.modal_edit_student),
        url(r'^teachers/', views.teachers),
        url(r'^add_teacher/', views.add_teacher),
        url(r'^edit_teacher/', views.edit_teacher),
        url(r'^get_all_class/', views.get_all_class),
        url(r'^modal_add_teacher/', views.modal_add_teacher),
        url(r'^test/', views.test),
        url(r'^layout/', views.layout),
        url(r'^login/', views.login),
    ]
    

    templates.layout.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
        <link rel="stylesheet" href="/static/plugins/font-awesome-4.7.0/css/font-awesome.css">
        <link rel="stylesheet" href="/static/css/commons.css">
        {% block css1 %}
        
        {% endblock %}
        <style>
    
        </style>
    </head>
    <body>
        <div class="pg-header">
            <div class="logo left">学生后台管理系统</div>
            <div class="avatar right" style="position: relative;">
                <img style=" 40px;height: 40px" src="/static/images/tx.png" alt="">
                <div class="user-info hide1">
                    <a href="">个人资料</a>
                    <a href="">注销</a>
                </div>
            </div>
            <div class="rmenus right">
                <a href=""><i class="fa fa-commenting-o" aria-hidden="true"></i> 消息</a>
                <a href=""><i class="fa fa-envelope-o" aria-hidden="true"></i> 邮件</a>
            </div>
    
        </div>
        <div class="pg-body">
            <div class="menus">
                <a href="/classes/">班级管理</a>
                <a href="/students/">学生管理</a>
                <a href="/teachers/">老师管理</a>
            </div>
            <div class="content">
                {% block body1 %}
                
                {% endblock %}
            </div>
        </div>
        {% block body2 %}
        
        {% endblock %}
        
        {% block script1 %}
            
        {% endblock %}
    </body>
    </html>
    

    templates.classes.html

    {% extends "layout.html" %}
    {% block css1 %}
        <link rel="stylesheet" href="/static/css/classes.css">
    {% endblock %}
    {% block body1 %}
        <div>
            <ol class="breadcrumb">
              <li><a href="#">首页</a></li>
    {#          <li><a href="#">班级管理</a></li>#}
              <li class="active">班级管理</li>
            </ol>
        </div>
        <div style=" 1000px;margin: 20px">
            <div style="margin: 10px 0;">
                <a href="/add_class/" class="btn btn-primary">添加班级</a>
                <a href="#" onclick="showModal();" class="btn btn-info">对话框添加</a>
            </div>
            <div>
                <table class="table table-striped table-bordered table-hover">
                    <thead>
                    <tr>
                        <th>ID</th>
                        <th>班级名称</th>
                        <th>操作</th>
                    </tr>
                    </thead>
                    <tbody>
                        {% for row in class_list %}
                        <tr>
                            <td>{{ row.id }}</td>
                            <td>{{ row.class_name }}</td>
                            <td>
                                <a href="/del_class/?id={{ row.id }}" class="glyphicon glyphicon-trash">删除 |</a>
                                <a href="#" onclick="return modalEdit(this);" class="glyphicon glyphicon-pencil">对话框编辑 |</a>
                                <a href="/edit_class/?id={{ row.id }}" class="glyphicon glyphicon-pencil">编辑</a>
                            </td>
                        </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
            <nav aria-label="Page navigation">
              <ul class="pagination">
                <li>
                  <a href="#" aria-label="Previous">
                    <span aria-hidden="true">&laquo;</span>
                  </a>
                </li>
                <li><a href="#">1</a></li>
                <li><a href="#">2</a></li>
                <li><a href="#">3</a></li>
                <li><a href="#">4</a></li>
                <li><a href="#">5</a></li>
                <li>
                  <a href="#" aria-label="Next">
                    <span aria-hidden="true">&raquo;</span>
                  </a>
                </li>
              </ul>
            </nav>
        </div>
    
    {% endblock %}
    
    {% block body2 %}
    <div id="shadow" class="hide"></div>
    <div id="modal" class="hide">
        <form action="/modal_add_class/" method="post">
            <p><input type="text" name="class_name" id="class_name"></p>
            <input type="button" value="提交" onclick="AjaxSend();">
            <input type="button" value="取消" onclick="cancleModal();">
            <span id="errormsg"></span>
        </form>
    </div>
    <div id="editModal" class="hide">
        <h3>编辑框</h3>
        <form action="/modal_add_class/" method="post">
            <p><input type="text" name="class_name" id="edit_class_name"></p>
            <p><input type="text" name="class_id" style="display: none" id="edit_class_id"></p>
            <input type="button" value="提交" onclick="editAjaxSend();">
            <input type="button" value="取消" onclick="cancleModal();">
            <span id="errormsg"></span>
        </form>
    </div>
    {% endblock %}
    
    {% block script1 %}
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script>
        function showModal(){
            document.getElementById('shadow').classList.remove('hide');
            document.getElementById('modal').classList.remove('hide');
        }
    
        function cancleModal() {
            document.getElementById('shadow').classList.add('hide');
            document.getElementById('modal').classList.add('hide');
            document.getElementById('editModal').classList.add('hide');
        }
    
        function AjaxSend() {
            $.ajax({
                url: '/modal_add_class/', // 提交地址
                type: 'POST',             // 提交方式
                data: {'class_name': $('#class_name').val()},  // 提交数据
                success: function (data) { // 当服务端处理完成后,返回数据时,该函数自动调用
                    // data 为返回的数据
                    if(data == 'ok'){
    {#                        location.href='/classes/';#}
                        location.reload();
                    }else{
                        $('#errormsg').text(data);
                    }
                }
            })
        }
    
        function modalEdit(self) {
            document.getElementById('shadow').classList.remove('hide');
            document.getElementById('editModal').classList.remove('hide');
            /*
            1.获取当前标签
            2.当前标签父标签的上方的标签
            3.获取当前行班级名,放入编辑框
             */
            var row = $(self).parent().prevAll();
            var content = $(row[0]).text();
            $('#edit_class_name').val(content);
            var class_id=$(row[1]).text();
            $('#edit_class_id').val(class_id)
        }
    
        function editAjaxSend() {
            var class_id = $('#edit_class_id').val();
            var class_name = $('#edit_class_name').val();
    
            $.ajax({
                url:'/modal_edit_class/',
                type:'POST',
                data: {'class_id':class_id,'class_name':class_name},
                success:function (arg) {
                    // arg 是字符串类型
                    // JSON.parse(字符串) => 对象
                    // JSON.stringify(对象) => 字符串
                    arg = JSON.parse(arg);
                    if(arg.status){
                        location.reload();
                    }else{
                        alert(arg.message);
                    }
                }
            })
        }
    </script>
    {% endblock %}
    

    templates.teachers.html

    {% extends "layout.html" %}
    {% block css1 %}
        <style>
            .shadow{
                position: fixed;
                top: 0;
                right: 0;
                bottom: 0;
                left: 0;
                background-color: black;
                opacity: 0.3;
                z-index: 999;
            }
            .add_modal,.edit_modal{
                position: fixed;
                top: 50%;
                left: 50%;
                 400px;
                height: 300px;
                margin-top: -150px;
                margin-left: -200px;
                z-index: 1000;
                background-color: white;
            }
            .hide{
                display: none;
            }
            .loading{
                position: fixed;
                 32px;
                height: 32px;
                left: 50%;
                top:50%;
                margin-left: -16px;
                margin-top: -16px;
                background-image: url("/static/images/loading.gif");
            }
    </style>
    {% endblock %}
    
    {% block body1 %}
        <div>
            <ol class="breadcrumb">
              <li><a href="#">首页</a></li>
    {#          <li><a href="#">老师管理</a></li>#}
              <li class="active">老师管理</li>
            </ol>
        </div>
        <div style=" 1200px;margin: 20px">
            <div style="margin-bottom: 20px">
                <a href="/add_teacher/" class="btn btn-primary">添加老师</a>
                <a href="#" id="btnAdd" class="btn btn-info">对话框添加</a>
            </div>
            <div>
                <table class="table table-striped table-bordered table-hover">
                    <thead>
                    <tr>
                        <th>ID</th>
                        <th>老师姓名</th>
                        <th>任教班级</th>
                        <th>操作</th>
                    </tr>
                    </thead>
                    <tbody>
                        {% for row in teacher_list %}
                        <tr>
                            <td>{{ row.teacher_id }}</td>
                            <td>{{ row.teacher_name }}</td>
                            <td>
                                {% for item in  row.class_name %}
                                    <span style="display: inline-block;margin-right: 10px;">{{ item }}</span>
                                {% endfor %}
                            </td>
                            <td>
                                <a href="/edit_teacher/?teacher_id={{ row.teacher_id }}">编辑</a>
                                <a>删除</a>
                            </td>
                        </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        <nav aria-label="Page navigation">
              <ul class="pagination">
                <li>
                  <a href="#" aria-label="Previous">
                    <span aria-hidden="true">&laquo;</span>
                  </a>
                </li>
                <li><a href="#">1</a></li>
                <li><a href="#">2</a></li>
                <li><a href="#">3</a></li>
                <li><a href="#">4</a></li>
                <li><a href="#">5</a></li>
                <li>
                  <a href="#" aria-label="Next">
                    <span aria-hidden="true">&raquo;</span>
                  </a>
                </li>
              </ul>
            </nav>
        </div>
    {% endblock %}
    
    {% block body2 %}
        <div class="shadow hide"></div>
        <div class="add_modal hide">
            <p>
                <input id="addTeacherName" type="text" name="teacher_name" placeholder="老师姓名">
            </p>
            <p>任教班级
                <select multiple size="10" id="addClassIds" name="class_id">
    
                </select>
            </p>
            <input id="btnAddTeacher" type="button" value="添加">
            <input id="btnCancelModal" type="button" value="取消">
            <span id="addErrorMsg"></span>
    
        </div>
        <div id="loading" class="loading hide"></div>
    {% endblock %}
    
    {% block script1 %}
        <script src="/static/jquery-3.2.1.min.js"></script>
        <script>
            $(function () {
                bindAdd();
                bindBtnAddTeacher();
            });
            function bindAdd() {
                $('#btnAdd').click(function () {
                    $('#loading').removeClass('hide');
                    /*
                    发送ajax请求,获取所有班级信息
                    在班级列表下拉框中生成option
                     */
                    $.ajax({
                        url: '/get_all_class/',
                        type: 'POST',
                        dataType: 'JSON',
                        success:function (arg) {
                            // 将所有的数据添加到select option框
                            $.each(arg,function (i,row) {
                                $('.shadow,.add_modal').removeClass('hide')
                                var tag = document.createElement('option');
                                tag.innerHTML = row.class_name;
                                tag.setAttribute('value',row.class_id);
                                $('#addClassIds').append(tag);
                            })
                        }
                    })
    
                });
    
                $('#btnCancelModal').click(function () {
                    $('.shadow,.add_modal').addClass('hide')
    
    
                })
            }
    
            function bindBtnAddTeacher() {
                $('#btnAddTeacher').click(function () {
                    var teacher_name = $('#addTeacherName').val();
                    var class_id_list = $('#addClassIds').val();
                    console.log(teacher_name, class_id_list);
                    $.ajax({
                        url:'/modal_add_teacher/',
                        type: 'POST',
                        data: {'teacher_name': teacher_name,'class_id_list':class_id_list},
                        traditional:true,  // 如果提交的数据的值有列表,则需要添加此属性
                        dataType: 'JSON',
                        success:function (arg) {
                            if(arg.status){
                                location.reload();
                            }else{
    {#                            $('#addErrorMsg').innerText = arg.message;#}
                                alert(arg.message)
                            }
                        }
    
                    })
                })
            }
        </script>
    {% endblock %}
    
    
    static.css.classes.css
    .hide{
        display: none;
    }
    #shadow{
        position: fixed;
        left:0;
        top:0;
        right: 0;
        bottom: 0;
        background-color: black;
        opacity: 0.4;
        z-index: 999;
    }
    #modal,#editModal{
        z-index: 1000;
        position: fixed;
        left: 50%;
        top: 50%;
        height: 300px;
         400px;
        background-color: white;
        margin-left: -200px;
        margin-top: -150px;
    }
    
    static.css.commons.css
    body{
        margin: 0;
    }
    .left{
        float: left;
    }
    .right{
        float: right;
    }
    .pg-header{
        height: 48px;
        min- 1190px;
        line-height: 48px;
        background-color: #2aabd2;
    }
    .menus{
         200px;
        position: absolute;
        left: 0;
        bottom: 0;
        top: 48px;
        border-right: 1px solid #dddddd;
        background-color: #dddddd;
    
    }
    .content{
        position: absolute;
        left: 200px;
        right: 0;
        top: 48px;
        bottom: 0;
        min- 990px;
        overflow: scroll;
        z-index: 99;
    }
    .pg-header .logo{
        color: white;
        font-size: large;
         200px;
        text-align: center;
        border-right: 1px solid red;
    }
    
    .pg-header .rmenus a{
        display: inline-block;
    
        padding: 0 15px;
        color: white;
    }
    .pg-header .rmenus a:hover{
        background-color: gold;
    }
    .pg-header .avatar{
        padding: 0 20px;
    }
    .pg-header .avatar img{
        border-radius: 50%;
    }
    .pg-header .avatar .user-info {
        120px;
        position: absolute;
        top: 48px;
        right: 2px;
        background-color: white;
        z-index: 100;
        border: 1px solid #dddddd;
    }
    .pg-header .avatar .user-info a{
        display: block;
        text-align: center;
    }
    .hide1{
        display: none;
    }
    .pg-header .avatar:hover .user-info{
        display: block;
    }
    
    .pg-body .menus a{
        display: block;
        padding: 10px 5px;
        border-bottom: solid 1px white;
        text-align: center;
    }
    
    • Cookie是保存在用户浏览器端的键值对
    • 服务端可以向用户浏览器端写cookie
    • 客户端每次发起请求时,会携带cookie去

    cookie用途:

    • 用户登录,保持用户登录状态
    • 投票系统(cookie禁用可破解)

    app01.views.py

    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
        elif request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            if username == 'alex' and password == '123':
                obj = redirect('/classes/')
                # obj.set_cookie('ticket','dhffjalih',max_age=10)
                # set_cookie参数:
                # 第一个参数 key
                # 第二个参数 value
                # max_age:超时时间,单位秒
                # path:生效的路径 默认为 / 全局生效
                # domain:生效的域名  默认为当前域名 做单点登录时会用到
                #
                # 设置加密cookie
                obj.set_signed_cookie('ticket','dhffjalih',salt='abc')
                return obj
            else:
                return render(request, 'login.html')
    
    def classes(request):
        # 去请求的cookie中找凭证
        # tk = request.COOKIES.get('ticket')
        # 获取加密cookie
        tk = request.get_signed_cookie('ticket',salt='abc')
        if not tk:
            return redirect('/login/')
        conn = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            passwd='123456',
            db='db03',
            charset='utf8'
        )
        cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
        cursor.execute(
            'select id,class_name from class order by id;'
        )
        class_list = cursor.fetchall()
        cursor.close()
        conn.close()
        return render(request, 'classes.html', {'class_list': class_list})
    

    PS:可以用装饰器完成所有函数的认证登录功能

  • 相关阅读:
    用Python学分析
    用Python学分析
    描述性统计指标
    用Python学分析
    Python练习:哥德巴赫猜想
    用Python学分析
    用Python学分析:集中与分散
    用Python学分析
    Ubuntu安装中文输入法
    Kali Linux ettercap的使用
  • 原文地址:https://www.cnblogs.com/wanyuetian/p/7106267.html
Copyright © 2020-2023  润新知