Django之学员管理三
Django之学员管理三
web框架的本质:
本质是客户端和服务端的交互。用socket实现。
socket客户端(浏览器)
2、发送ip和端口,http://www.baidu.com:80/index/ (http://www.baidu.com:80) 为ip和端口,(/index/ )是url。客户端往服务端发送请求时,是要分post和get两种请求方式。
4、接受响应,普通的响应就是正常的拿到响应体浏览器是处理呈现,而重定向是要再发一次http请求,进行一次跳转才可以。
socket服务端(服务器)
1、服务端socket先运行起来进行监听 while循环来持续监听ip和端口,等待客户连接。
3、接受请求,处理并返回相应的结果,返回的本质是一堆字符串。返回的有响应头和响应体。还有一种响应方式,是重定向返回,在重定向返回里是没有响应体的,只有响应头。在响应头里有一区别是多了一个location,在location里定义要响应跳转的url。
django的web框架:
a、创建project:django-admin startproject mysite
b、配置:模板,静态文件,csrf
c、路由关系:url-》函数
d、视图函数:
def index(request):
获取的:request.method
request.POST
request.GET
返回的:return redirect("url")
return render(request, "模板路径", { } )
return HttpResponse("字符串")
e、模板渲染:{% for %} 和 {% if %}
Ajax的本质流程:
基于jQuery实现的ajax,
$.ajax({
url:"",
type:"",
data:{k1:"v1"},
success:function(arg){
}
})
小知识点:在onclick的前面加一个href的url,是先执行onclick的事件,在跳转到href的url。但是如何在ajax里的对应事件执行完,返回return False,那么在href里的url就不在执行啦。这个方法用在form表单中。
对班级表实现ajax方式的编辑删除操作(对话框的单表的编辑操作):
注意点:一定要注意前后端的标签id是否一致,和$(#' ') 里面要拿取的标签id前的#符号,否则会找不到值,并且前端不会有报错。
前端操作代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>classes</title> <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{ 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> <h1>classes_list</h1> <div> <a href="/add_class/">添加</a> | <a onclick="showModal();">对话框添加</a> </div> <table> <thead> <tr> <th>ID</th> <th>班级名称</th> <th>操作</th> </tr> </thead> <tbody> {% for item in class_lsit %} <tr> <td>{{ item.nid }}</td> <td>{{ item.title }}</td> <td> <a href="/del_class/?nid={{ item.nid }}">删除</a> | <a onclick="modelEdit(this);">对话框编辑</a> | <a href="/edit_class/?nid={{ item.nid }}">编辑</a> </td> </tr> {% endfor %} </tbody> </table> <div id="shadow" class="shadow hide"></div> <div id="modal" class="modal hide"> <p>添加班级:<input id="title" type="text" name="title" placeholder="班级名称"></p> <input type="button" value="submit" onclick="AjaxSend();"/> <input type="button" value="cancel" onclick="cancleModal();"/><span id="errormsg"></span> </div> <div id="editModel" class="modal hide"> <h3>编辑框</h3> <p> <input id="editId" type="text" name="nid" style="display: none" /> <input id="editTitle" type="text" name="title" /> </p> <input type="button" value="submit" onclick="editAjaxSend();" /><span id="errormsg"></span> <input type="button" value="cancel" onclick="cancleModal();" /> </div> <script src="/static/jquery-1.12.4.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('editModel').classList.add('hide'); } function AjaxSend(){ $.ajax({ url:'/modal_add_classes_ajax/', //往哪里提交 type:'POST', //以什么方式提交 data:{"title":$("#title").val()}, //拿到全段输入的值 success:function (data) { //当服务端处理完成后,返回数据时,该函数自动调用 //data是服务端返回的值 console.log(data); if(data=="ok"){ location.href='/classes/'; //指定提交成功后跳转到哪里 }else { $('#errormsg').text(data); } } }) } function modelEdit(ths) { document.getElementById("shadow").classList.remove("hide"); //找到遮罩层,并去挑遮罩层 document.getElementById("editModel").classList.remove("hide"); /* 1、获取当前点击标签 2、获取当前标签的父标签,再找其上方标签 3、获取当前行班级名称,赋值到编辑对话框中 */ var row = $(ths).parent().prevAll() //$(ths)是获取当前标签。 .parent是当前父标签。 .prevAll是当前级标签的上面所有的标签。 console.log(row); var content = $(row[0]).text(); //用列表取值的方式获取title。 .text是转成文本信息。 $('#editTitle').val(content); //找到title给他赋值给val里。 var contentId = $(row[1]).text(); $('#editId').val(contentId); } function editAjaxSend() { var nid = $('#editId').val(); //提交操作里前端获取id var content = $('#editTitle').val(); // 提交操作,前端获取新输入的值 console.log(nid,content); $.ajax({ url:'/modal_edit_classes_ajax/', type:"POST", data:{"nid":nid,"content":content}, success:function (arg) { // arg字符串类型 // JSON.parse(字符串) => 对象 // JSON.stringify(对象) => 字符串 arg = JSON.parse(arg); if(arg.status){ //location.href="/classes/" //这个是跳转 location.reload(); //这个是刷新 }else{ alert(arg.message); } } }) } </script> </body> </html>
views.py 的对应函数:
def modal_edit_classes_ajax(request): ret = {"status":True,"message":None} #当try代码块出现问题,可以用这种方式收集错误信息 try: nid = request.POST.get("nid") # 拿id print(nid) content = request.POST.get("content") #拿内容 print(content) sqlheper.modify("update classes set title=%s where nid=%s",[content,nid,]) print("1") except Exception as e: ret['status'] = False ret['message'] = "处理异常" # ret['message'] = str(e) #异常对象的内容,用字符串的形式拿到。 return HttpResponse(json.dumps(ret)) #用json.dumps的方法使的json将数据转成字符串,在发给前端
在单表的ajax里,编辑和添加操作,班级表和老师表是一致的。
下面,我们来研究一下如何实现一对多的ajax操作,也就是学生表的操作。在操作学生表中,对比操作单表而言,对了一个连表操作,那究竟如何在ajax中加以实现这个操作呐?下面我们来看一下如何实现吧!!!
我们先实现添加操作:
在这里说明一点,单表的ajax操作是用onclick的方式实现,那么在学生表里,我们就是jQuery实现一下,这样也是为了体验和运用两种绑定事件的方法。
实现步骤区别:在标签位,和onclick不同,在a标签里不写onclick,写id就好。在导入jQuery,然后添加$(function( { } ) )
students.html 代码实现:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>students</title> 6 <style> 7 .hide{ 8 display: none; 9 } 10 .shadow{ 11 position: fixed; 12 left: 0; 13 top: 0; 14 right: 0; 15 bottom: 0; 16 background-color: black; 17 opacity: 0.4; 18 z-index: 999; 19 } 20 .add-modal{ 21 z-index: 1000; 22 position: fixed; 23 left: 50%; 24 top: 50%; 25 height: 300px; 26 width: 400px; 27 background-color: white; 28 margin-left: -200px; 29 margin-top: -150px; 30 } 31 </style> 32 </head> 33 <body> 34 <h1>students_list</h1> 35 <div> 36 <a href="/add_students_add/">添加</a> 37 | 38 <a id="addModal">对话框添加</a> 39 </div> 40 <table> 41 <thead> 42 <tr> 43 <th>ID</th> 44 <th>学生姓名</th> 45 <th>所属班级</th> 46 <th>操作</th> 47 </tr> 48 </thead> 49 <tbody> 50 {% for item in students_list %} 51 <tr> 52 <td>{{ item.sid }}</td> 53 <td>{{ item.name }}</td> 54 <td>{{ item.title }}</td> 55 <td> 56 <a href="/del_students_del/?sid={{ item.sid }}">删除</a> 57 | 58 <a href="/edit_students_edit/?sid={{ item.sid }}">编辑</a> 59 | 60 <a onclick="">对话框编辑</a> 61 </td> 62 </tr> 63 {% endfor %} 64 </tbody> 65 </table> 66 67 <div id="shadow" class="shadow hide"></div> 68 69 <div id="add-Modal" class="add-modal hide"> 70 <p> 71 Name:<input id="addName" type="text" name="name" placeholder="Name"> 72 </p> 73 <p> 74 Classes: 75 <select id="addClassesId" name="classesID" > 76 {% for row in classes_list %} 77 <option value="{{ row.nid }}">{{ row.title }}</option> 78 {% endfor %} 79 </select> 80 </p> 81 <input id="btnAdd" type="button" value="添加" /> 82 <input id="btncancel" type="button" value="取消" /> 83 <span id="addError" style="color: red;"></span> 84 </div> 85 86 <script src="/static/jquery-1.12.4.js"></script> 87 <script> 88 //绑定事件。click进行绑定事件 89 $(function () { 90 $("#addModal").click(function () { 91 $("#shadow,#add-Modal").removeClass('hide'); 92 }) 93 94 $("#btncancel").click(function () { 95 $("#shadow,#add-Modal").addClass("hide"); 96 }) 97 98 $('#btnAdd').click(function () { 99 $.ajax({ 100 url:"/modal_add_students_modal/", 101 type:"POST", 102 data:{"name":$("#addName").val(),"classes_id":$("#addClassesId").val()}, 103 success:function (arg) { 104 //回调函数, 105 console.log(arg); //将数据发送给后台 106 arg = JSON.parse(arg); 107 if(arg.status){ 108 location.reload(); 109 }else{ 110 $("#addError").text(arg.message); 111 } 112 } 113 }) 114 }) 115 }) 116 117 </script> 118 </body> 119 </html>
view.py 的students表的ajax实现的后端代码:
1 def modal_add_students_modal(request): 2 ret = {"status":True,"message":None} 3 try: 4 name = request.POST.get("name") 5 classes_id = request.POST.get("classes_id") 6 sqlheper.modify('insert into students(name,classes_id) values(%s,%s)',[name,classes_id,]) 7 except Exception as e: 8 ret['status'] = False 9 ret['message'] = str(e) 10 11 return HttpResponse(json.dumps(ret))
在实现了students的ajax的添加操作后,来实现一下编辑操作。
编辑操作的点在于如何拿取班级信息,因为学生的姓名和id和单表一致,可是学生表是一对多的关联班级表,所以,如何解决班级的id获取是关键。
在编辑时,拿取班级ID和学生默认值是问题点的核心。
下面来实现一下students的编辑操作:
students.html 的学生编辑ajax操作的前端代码实现:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>students</title> 6 <style> 7 .hide{ 8 display: none; 9 } 10 .shadow{ 11 position: fixed; 12 left: 0; 13 top: 0; 14 right: 0; 15 bottom: 0; 16 background-color: black; 17 opacity: 0.4; 18 z-index: 999; 19 } 20 .add-modal{ 21 z-index: 1000; 22 position: fixed; 23 left: 50%; 24 top: 50%; 25 height: 300px; 26 width: 400px; 27 background-color: white; 28 margin-left: -200px; 29 margin-top: -150px; 30 } 31 </style> 32 </head> 33 <body> 34 <h1>students_list</h1> 35 <div> 36 <a href="/add_students_add/">添加</a> 37 | 38 <a id="addModal">对话框添加</a> 39 </div> 40 <table> 41 <thead> 42 <tr> 43 <th>ID</th> 44 <th>学生姓名</th> 45 <th>所属班级</th> 46 <th>操作</th> 47 </tr> 48 </thead> 49 <tbody> 50 {% for item in students_list %} 51 <tr> 52 <td>{{ item.sid }}</td> 53 <td>{{ item.name }}</td> 54 <td clsId="{{ item.classes_id }}">{{ item.title }}</td> 55 <td> 56 <a href="/del_students_del/?sid={{ item.sid }}">删除</a> 57 | 58 <a href="/edit_students_edit/?sid={{ item.sid }}">编辑</a> 59 | 60 <a class="btn-edit">对话框编辑</a> 61 </td> 62 </tr> 63 {% endfor %} 64 </tbody> 65 </table> 66 67 <div id="shadow" class="shadow hide"></div> 68 69 <div id="add-Modal" class="add-modal hide"> 70 <p> 71 Name:<input id="addName" type="text" name="name" placeholder="Name"> 72 </p> 73 <p> 74 Classes: 75 <select id="addClassesId" name="classesID" > 76 {% for row in classes_list %} 77 <option value="{{ row.nid }}">{{ row.title }}</option> 78 {% endfor %} 79 </select> 80 </p> 81 <input id="btnAdd" type="button" value="add" /> 82 <input onclick="cancleModal();" type="button" value="cancel" /> 83 <span id="addError" style="color: red;"></span> 84 </div> 85 86 <div id="editModal" class="add-modal hide"> 87 <h3>编辑学生信息</h3> 88 <p> 89 学生姓名:<input id="editName" type="text" name="name" placeholder="Name"> 90 <input type="text" id="editId" style="display: none"> 91 </p> 92 <p> 93 所属班级: 94 <select id="editClassesId" name="classes_id" > 95 {% for classes in classes_list %} 96 <option value="{{ classes.nid }}">{{ classes.title }}</option> 97 {% endfor %} 98 </select> 99 </p> 100 <input id="btnEdit" type="button" value="update"> 101 <input onclick="cancleModal();" type="button" value="cancel"> 102 <span id="editError" style="color: red;"></span> 103 </div> 104 105 <script src="/static/jquery-1.12.4.js"></script> 106 <script> 107 //绑定事件。click进行绑定事件 108 $(function () { 109 $("#addModal").click(function () { 110 $("#shadow,#add-Modal").removeClass('hide'); 111 }) 112 113 $('#btnAdd').click(function () { 114 $.ajax({ 115 url:"/modal_add_students_modal/", 116 type:"POST", 117 data:{"name":$("#addName").val(),"classes_id":$("#addClassesId").val()}, 118 success:function (arg) { 119 //回调函数, 120 console.log(arg); //将数据发送给后台 121 arg = JSON.parse(arg); 122 if(arg.status){ 123 location.reload(); 124 }else{ 125 $("#addError").text(arg.message); 126 } 127 } 128 }) 129 }) 130 131 $(".btn-edit").click(function () { 132 $("#shadow,#editModal").removeClass("hide"); 133 /* 134 1.获取当前标签 $(this) 就是当期标签 135 */ 136 var tds = $(this).parent().prevAll(); 137 var studentsId = $(tds[2]).text(); 138 var studentsName = $(tds[1]).text(); 139 var classesId = $(tds[0]).attr("clsId"); 140 console.log(studentsId,studentsName,classesId); 141 142 //赋值操作,也就是带默认值 143 $("#editId").val(studentsId); 144 $("#editName").val(studentsName); 145 $("#editClassesId").val(classesId); 146 147 }) 148 149 $("#btnEdit").click(function () { 150 $.ajax({ 151 url:'/modal_edit_students_modal/', 152 type:"POST", 153 data:{"sid":$("#editId").val(),"name":$("#editName").val(),"classes_id":$("#editClassesId").val()}, 154 dataType:"JSON", //这里的JSON就直接做了JSON的序列化操作,执行JSON.parse(arg) 在这里JSON会先把arg先转换为对象 155 success:function (arg) { 156 if (arg.status){ 157 location.reload(); 158 }else{ 159 $("#editError").text(arg.message); 160 } 161 } 162 }) 163 }) 164 }) 165 166 //取消操作 167 function cancleModal() { 168 document.getElementById('shadow').classList.add('hide'); 169 document.getElementById('add-Modal').classList.add('hide') 170 document.getElementById('editModal').classList.add('hide') 171 } 172 173 </script> 174 </body> 175 </html>
views.py 的学生编辑ajax后端代码实现:
def modal_edit_students_modal(request): ret = {"status":True,"message":None} try: sid = request.POST.get("sid") name = request.POST.get("name") classes_id = request.POST.get("classes_id") sqlheper.modify("update students set name=%s,classes_id=%s where sid=%s", [name,classes_id,sid,]) except Exception as e: ret["status"] = False ret["message"] = str(e) return HttpResponse(json.dumps(ret))
一对多的操作在学生表的操作里展现的可以简单说明啦,那么下面,我们来看一下多对多的操作:
老师班级关系表:
id teacher_id class_id
多对多建表操作请去目录数据库查看mysql多对多操作。
先实现查操作,就是在前端显示出老师和班级的关联:
但是,多对多的展示,是要有一个基准表的,一谁去查,比如我们的老师班级关系表,我们可以以老师为基准,去查看这个老师都授课了那些班级,也可以以班级表为基准,来查看这个班级都有那些老师来授课,并且有一点,在展示时,不能展示teacher_id 和 class_id 的id号,而是老师的姓名或班级的名称。
多对多操作:查看
我们这里以老师表为基准,来展示一下, 所以就创建一个teacherandclass。
问题点,如何在一行里显示一个老师任课的多个班级,是要将班级的字典都存在在一个列表里,那样就可以实现一行数据里显示一个老师或班级,所属的多个班级或老师啦。
teacherandclass.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>teacherandclass</title> 6 </head> 7 <body> 8 <h1>老师和班级关系表</h1> 9 <table border="1"> 10 <thead> 11 <tr> 12 <th>ID</th> 13 <th>Teacher name</th> 14 <th>Class name</th> 15 <th>操作</th> 16 </tr> 17 </thead> 18 <tbody> 19 {% for foo in teacher_class_list %} 20 <tr> 21 <td>{{ foo.tid }}</td> 22 <td>{{ foo.name }}</td> 23 <td> 24 {% for item in foo.titles %} 25 <span style="display: inline-block;padding: 5px;border: 1px solid red;">{{ item }}</span> 26 {% endfor %} 27 </td> 28 <td> 29 <a >Edit</a> 30 | 31 <a >Delete</a> 32 </td> 33 </tr> 34 {% endfor %} 35 </tbody> 36 </table> 37 </body> 38 </html>
在后端的teacherandclass.py 函数:
1 def teacherandclass(request): 2 teacher_class_list = sqlheper.get_list(""" 3 select teacher.nid as tid,teacher.`name`,classes.title from teacher 4 LEFT JOIN teacherandclasses ON teacher.nid = teacherandclasses.teacher_id 5 LEFT JOIN classes ON classes.nid = teacherandclasses.class_id; 6 """,[]) 7 print(teacher_class_list) 8 result = {} #定义一个空字典,用来存放 teacher_class_list 的数据 9 for row in teacher_class_list: #循环teacher_class_list 列表,将列表的每一个字典取出来处理 10 tid = row["tid"] #拿取字典的每一个tid进行判断 11 if tid in result: #如果tid在已有的result字典里,就将这个tid所属的title加进新定义的titles里 12 result[tid]["titles"].append(row["title"]) 13 else: #如果没有的话,就将新的tid按照新定义的形式,加到result里 14 result[tid] = {"tid":row["tid"],"name":row["name"],"titles":[row["title"],]} 15 return render(request,"teacherandclass.html",{"teacher_class_list":result.values()})
以上是多对多的查看操作的实现方式。
那么多对多的添加和编辑操作,如何实现呐!请看下回分解,在下一期,我们不仅仅会实现多对多的添加和编辑,还会有ajax的多对多的操作。
--------- END ----------