Python全栈之路-Django(五)

1 HTTP请求生命周期

请求头 -> 提取URL -> 路由关系匹配 -> 函数(模板 + 数据渲染) -> 返回给用户(响应头 + 响应体)

补充:模板渲染是在后台完成

2 老师管理(多对多)

  • 需求1:添加老师信息(新URL)
  • 需求2:编辑老师信息(新URL)
  • 需求3:添加老师信息(Ajax)

url.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),
]

app01.views.py

def teachers(request):
    teacher_list = sqlhelper.get_list(
        'select teacher.id as teacher_id,teacher.teacher_name,class.class_name \
        from teacher left join teacher_class on teacher.id=teacher_class.teacher_id \
        left join class on teacher_class.class_id=class.id order by teacher.id;',
        []
    )
    class_list = sqlhelper.get_list(
        'select id as class_id,class_name from class;',
        []
    )
    result = {}

    for item in teacher_list:
        teacher_id = str(item['teacher_id'])
        if teacher_id in result:
            result[teacher_id]['class_name'].append(item['class_name'])
        else:
            result[teacher_id] = {
                'teacher_id': teacher_id,
                'teacher_name': item['teacher_name'],
                'class_name': [item['class_name'], ]
            }
    return render(request, 'teachers.html', {'teacher_list': result.values(), 'class_list': class_list})


def add_teacher(request):
    if request.method == 'GET':
        class_list = sqlhelper.get_list(
            'select id,class_name from class;',
            []
        )
        print(class_list)
        return render(request, 'add_teacher.html', {'class_list': class_list})
    elif request.method == 'POST':
        teacher_name = request.POST.get('teacher_name')
        class_ids = request.POST.getlist('class_ids')
        print(teacher_name, class_ids)
        # 老师表中添加一条数据

        teacher_id = sqlhelper.create(
            'insert into teacher(teacher_name) VALUES(%s);',
            [teacher_name, ]
        )
        # 老师和班级关系表插入多条数据
        # 方案1:连接多次 commit多次
        # for item in class_ids:
        #     sqlhelper.modify(
        #         'insert into teacher_class(teacher_id,class_id) VALUES(%s,%s);',
        #         [teacher_id, item]
        #     )
        # 方案2:连接一次 commit多次
        # obj = sqlhelper.SqlHelper()
        # for item in class_ids:
        #     obj.modify(
        #         'insert into teacher_class(teacher_id,class_id) VALUES(%s,%s);',
        #         [teacher_id, item]
        #     )
        # obj.close()
        # 方案3:连接一次 commit一次
        temp_list = []
        for item in class_ids:
            temp = (teacher_id, item)
            temp_list.append(temp)
        obj = sqlhelper.SqlHelper()
        obj.multiple_modify(
            'insert into teacher_class(teacher_id,class_id) VALUES(%s,%s);',
            temp_list
        )
        obj.close()

        return redirect('/teachers/')


def edit_teacher(request):
    if request.method == 'GET':
        teacher_id = request.GET.get('teacher_id')
        print(teacher_id)
        print(type(teacher_id))
        obj = sqlhelper.SqlHelper()
        teacher_info = obj.get_one(
            'select id,teacher_name from teacher where id=%s;',
            [teacher_id, ]
        )
        class_id_list = obj.get_list(
            'select class_id from teacher_class where teacher_id=%s',
            [teacher_id, ]
        )
        class_list = obj.get_list(
            'select id as class_id,class_name from class',
            []
        )
        temp_list = []
        print(class_id_list)
        for item in class_id_list:
            temp_list.append(item['class_id'])
        print(temp_list)
        class_id_list = temp_list
        obj.close()
        return render(request,
                      'edit_teacher.html',
                      {'teacher_info': teacher_info, 'class_id_list': class_id_list, 'class_list': class_list}
                      )
    elif request.method == 'POST':
        teacher_id = request.GET.get('teacher_id')
        teacher_name = request.POST.get('teacher_name')
        class_ids = request.POST.getlist('class_ids')
        obj = sqlhelper.SqlHelper()
        # 更新老师表
        obj.modify(
            'update teacher set teacher_name=%s where id=%s;',
            [teacher_name, teacher_id]
        )
        # 更新老师班级表  采用全部删除后再添加方案
        # 获取老师班级对应列表
        # 方式1:传统方式
        # temp_list = []
        # for item in class_ids:
        #     temp = (teacher_id, item)
        #     temp_list.append(temp)
        # 方式2:map + lambda
        temp_list = map(lambda x: (teacher_id, x), class_ids)

        obj = sqlhelper.SqlHelper()
        obj.modify(
            'delete from teacher_class where teacher_id=%s;',
            [teacher_id]
        )
        obj.multiple_modify(
            'insert into teacher_class(teacher_id,class_id) VALUES(%s,%s);',
            temp_list
        )
        obj.close()
        return redirect('/teachers/')

def get_all_class(request):
    obj = sqlhelper.SqlHelper()
    class_list = obj.get_list(
        'select id as class_id,class_name from class;',
        []
    )
    time.sleep(1)
    obj.close()
    return HttpResponse(json.dumps(class_list))


def modal_add_teacher(request):
    ret = {'status': True, 'message': None}
    try:
        teacher_name = request.POST.get('teacher_name')
        class_id_list = request.POST.getlist('class_id_list')
        teacher_id = sqlhelper.create(
            'insert into teacher(teacher_name) VALUES(%s);',
            [teacher_name, ]
        )
        temp_list = []
        for item in class_id_list:
            temp = (teacher_id, item)
            temp_list.append(temp)
        obj = sqlhelper.SqlHelper()
        obj.multiple_modify(
            'insert into teacher_class(teacher_id,class_id) VALUES(%s,%s);',
            temp_list
        )
        obj.close()
    except Exception as e:
        ret['status'] = False
        ret['message'] = str(e)

    return HttpResponse(json.dumps(ret))

template.teachers.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
        <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%;
            width: 400px;
            height: 300px;
            margin-top: -150px;
            margin-left: -200px;
            z-index: 1000;
            background-color: white;
        }
        .hide{
            display: none;
        }
        .loading{
            position: fixed;
            width: 32px;
            height: 32px;
            left: 50%;
            top:50%;
            margin-left: -16px;
            margin-top: -16px;
            background-image: url("/static/images/loading.gif");
        }

    </style>
</head>
<body>
    <h1>老师列表</h1>
    <div>
        <a href="/add_teacher/">添加老师</a>
        <a href="#" id="btnAdd">对话框添加</a>
    </div>
    <table>
        <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 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>
    <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>
</body>
</html>

template.add_teacher.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>添加老师</h1>
    <form action="/add_teacher/" method="post">
        <p><input type="text" name="teacher_name" placeholder="老师姓名"></p>
        <p>
            <select multiple size="5" name="class_ids">
                {% for row in class_list %}
                <option value="{{ row.id }}">{{ row.class_name }}</option>
                {% endfor %}
            </select>
        </p>
        <input type="submit" value="提交">
    </form>
</body>
</html>
template.edit_teacher.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>编辑老师</h1>
    <form action="/edit_teacher/?teacher_id={{ teacher_info.id }}" method="post">
        <p><input type="text" name="teacher_name" value="{{ teacher_info.teacher_name }}"></p>
        <p>
            <select multiple size="5" name="class_ids">
                {% for row in class_list %}
                    {% if row.class_id in class_id_list %}
                <option selected value="{{ row.class_id }}">{{ row.class_name }}</option>
                    {% else %}
                <option value="{{ row.class_id }}">{{ row.class_name }}</option>
                    {% endif %}
                {% endfor %}
            </select>
        </p>
        <input type="submit" value="提交">
    </form>
</body>
</html>

3 初识bootstrap

template.classes.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/bootstrap-3.3.7-dist/css/bootstrap.min.css"> //压缩版本,用于生产环境#}
    <style>
        .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;
            width: 400px;
            background-color: white;
            margin-left: -200px;
            margin-top: -150px;
        }
    </style>
</head>
<body>
    <div style="width: 700px;margin: 0 auto;">
    <h1>班级列表</h1>
    <div style="margin: 10px 0;">
        <a href="/add_class/" class="btn btn-primary">添加班级</a>
        <a href="#" onclick="showModal();" class="btn btn-info">对话框添加</a>
    </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 %}a
        </tbody>
    </table>
    </div>
    <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>

    <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>
</body>
</html>

posted on 2017-07-02 10:25  万越天  阅读(204)  评论(0编辑  收藏  举报