使用另外一种方式,对老师表的添加、编辑。使用JSON来绑定事件
1.查询
student.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>学生列表</h1>
<div>
<a href="/add_student/">添加</a>
<a id="addModal">对话框添加</a>
</div>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>学生姓名</th>
<th>学生所属班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for row in student_list %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.name }}</td>
<td clsId ="{{ row.class_id }}">{{ row.title }}</td> {# //<td clsId ="{{ row.class_id }}">自定义属性,班级名里面包含班级ID#}
{# <td>{{ row.class_id }}</td>#}
<td><a href="/edit_student/?sid={{row.id}}">编辑</a>
| <a class="btn_edit">对话框编辑</a>
| <a href="/del_student/?sid={{row.id}}">删除</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<style>
.hide{
display: none;
}
.shadow{
/*相对于窗口*/
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
background-color: black;
opacity: 0.4;
z-index: 999;
}
.add_modal{
/*相对于窗口*/
position: fixed;
left: 50%;
top:50%;
width: 400px;
height: 300px;
z-index: 1000;
background-color: white;
margin-left: -200px; {#左移200像素 #}
margin-top: -200px;
}
.edit_modal{
/*相对于窗口*/
position: fixed;
left: 50%;
top:50%;
width: 400px;
height: 300px;
z-index: 1000;
background-color: white;
margin-left: -200px; {#左移200像素 #}
margin-top: -200px;
}
</style>
{#遮罩层#}
<div id="shadow" class="shadow hide"></div>
{#添加模态框#}
<div id="add_Modal" class="add_modal hide" >
<h3>添加学生</h3>
<p>
姓名:<input id="addName" type="text" name="name" placeholder="姓名:"> {# placeholder="姓名:输入框里面默认提示的值,支持高版本浏览器,低版本可能不支持 #}
</p>
<p>班级:
<select id="addClassId" name="addClassId">{# 下拉框 #}
{% for row in class_list %}
<option value="{{ row.id }}" > {{ row.title }}</option>
{% endfor %}
</select>
</p>
<input id="btnAdd" type="button" value="添加">
<input id="exitModel" type="button" value="取消"><span id="addError" style="color: red"></span>
</div>
{#学生编辑框#}
<div id="editModal" class="edit_modal hide" >
<h3>编辑学生信息</h3>
<p>
姓名:<input id="editName" type="text" name="name" placeholder="姓名:"> {# placeholder="姓名:输入框里面默认提示的值,支持高版本浏览器,低版本可能不支持 #}
<input type="text" id="editId" style="display: none"> {# 把学生的ID隐藏起来 #}
</p>
<p>班级:
<select id="editClassId" name="ClassId">{# 下拉框 #}
{% for row in class_list %}
<option value="{{ row.id }}" > {{ row.title }}</option>
{% endfor %}
</select>
</p>
<input id="btnEdit" type="button" value="更新">
<input id="exit_edit_Model" type="button" value="取消"><span id="addError" style="color: red"></span>
</div>
<script src="/static/jquery-2.1.4.min.js"></script>
<script>
{#要绑定事件就要先找到它 id="addModal#}
$(function () {
{#隐藏模态窗口#}
$('#exitModel').click(function () {
$('#shadow,#add_Modal').addClass('hide');
{#$('#shadow,').addClass('hide');#}
})
{#隐藏模态窗口#}
$('#exit_edit_Model').click(function () {
$('#shadow,#editModal').addClass('hide');
{#$('#shadow,').addClass('hide');#}
})
{# 显示提交模态框 #}
$('#addModal').click(function () { {# 找到id 为addModal ,然后执行这个函数#}
//alert(123);
// return false;//在这里可以阻止默认事件的发生 ,<a href="www.baidu.com" id="addModal">对话框添加</a> 里面的跳转百度网页就是默认事件
$('#shadow,#add_Modal').removeClass('hide');
});
{#添加提交按钮#}
$('#btnAdd').click(function () {
$.ajax({
url: '/modal_add_student/',
type: 'POST',
data: {'name': $('#addName').val(), 'class_id': $('#addClassId').val()},
success: function (arg) {
console.log(arg);
arg = JSON.parse(arg);
if (arg.status) {
location.reload();
} else {
$('#addError').text(arg.message);
}
}
})
})
{#显示编辑框#}
$('.btn_edit').click(function () { //class="btn_edit class绑定的事件用 . 开头, id="btnEdit"用"#"
$('#shadow,#editModal').removeClass('hide');
/* 找到当前标签,找到当前标签的父标签
1.获取当前标签 $(this)
2. 这个是以类的方式进行绑定的 <a class="btn_edit">对话框编辑</a>
* */
var tds = $(this).parent().prevAll();
var studentId = $(tds[2]).text();
var studentName= $(tds[1]).text();
var classId= $(tds[0]).attr('clsId'); // attr('claid') 这个是拿自定义属性的值
console.log(studentId,studentName,classId)
//赋值操作
$('#editId').val(studentId);
$('#editName').val(studentName);
$('#editClassId').val(classId);
})
{#提交编辑#}
$('#btnEdit').click(function () {
//发ajax请求
$.ajax({
url:'/modal_edit_student/',
type:'POST',
data:{'nid':$('#editId').val(),'name':$('#editName').val(),'class_Id':$('#editClassId').val()},
dataType:'JSON', //打上这个,在内部就会把arg先转化为对象 等同于下面的 JSON.parse(arg)
success:function (arg) {
// JSON.parse(arg) //反序列化,,字符串必须是要JSON格式
if(arg.status){
location.reload();
}else {
$('#editError').text(arg.message);
}
}
})
})
})
</script>
</body>
</html>
urls.py
path('modal_add_student/',views.modal_add_student),
path('modal_edit_student/',views.modal_edit_student),
views.py
#添加学生
def modal_add_student(request):
ret = {'status':True,'message':None}
try:
name = request.POST.get('name')
class_id = request.POST.get('class_id')
sqlheper.add_list('insert into student(name,class_id) value (%s,%s)',[name,class_id,])
except Exception as e:
ret['status'] = False
ret['message'] = str(e)
return HttpResponse(json.dumps(ret))
#编辑学生
def modal_edit_student(request):
ret = {'status':True,'message':None}
try:
nid = request.POST.get('nid')
name = request.POST.get('name')
class_id = request.POST.get('class_Id')
print(class_id)
sqlheper.add_list('update student set name=%s,class_id=%s where id =%s',[name,class_id,nid,])
except Exception as e:
ret['status'] = False
ret['message'] = str(e)
return HttpResponse(json.dumps(ret))
PS:a.js阻止默认事件的发送
b.location.reload();重新加载当前页面(刷新)
c.HttpResponse(json.dumps(xxx))把一个字典放进去,然后序列化
d.JSON.parse() 反序列化
一对多
PS:a
<a href="www.baidu.com" id="addModal">对话框添加</a> 里面的跳转百度网页就是默认事件
$('#addModal').click(function () { {# 找到id 为addModal ,然后执行这个函数#}
alert(123);
return false;//在这里可以阻止默认事件的发生 ,<a href="www.baidu.com" id="addModal">对话框添加</a> 里面的跳转百度网页就是默认事件
})
2.多表操作
以老师表为例,在列表上增加老师的任课班级。效果如下图
新建teacher.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>老师列表</h1>
<div>
</div>
<table border="1" >
<thead>
<tr>
<th>老师ID</th>
<th>老师名称名称</th>
<th>任教班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for msg in teacher_list %}
<tr>
<td>{{ msg.tid }}</td>
<td>{{ msg.name }}</td>
<td>{% for foo in msg.titles %}
<span style="display: inline-block;padding: 5px;border: 1px solid red;">{{ foo }}</span>
{% endfor %}
</td>
<td><a>编辑</a>
<a >对话框编辑</a>|
<a>删除</a>
<a > 对话框删除 </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
views.py
#多对多,以老师表展示
def teachers(request):
teacher_list = sqlheper.get_list('''SELECT teacher.id as tid,teacher.name,class.title FROM teacher
LEFT JOIN teacher2class ON teacher.id = teacher2class.teacher_id
LEFT JOIN class ON class.id=teacher2class.class_id;
result = {}
for row in teacher_list:
tid = row['tid']
if tid in result:
result[tid]['titles'].append(row['title'])
else:
result[tid] = {'tid':row['tid'],'name':row['name'],'titles':[row['title'],]}
print(result)
return render(request,'teachers.html',{'teacher_list':result.values()})
由数据库读取出来的列表数据是这样的
# [{‘tid’: 1, ‘name’: ‘高老师’, ‘title’: ‘应用’},
# {‘tid’: 2, ‘name’: ‘李老师’, ‘title’: ‘应用’},
# {‘tid’: 1, ‘name’: ‘高老师’, ‘title’: ‘软件’},
# {‘tid’: 3, ‘name’: ‘王老师’, ‘title’: ‘软件’},
# {‘tid’: 3, ‘name’: ‘王老师’, ‘title’: ‘动漫’}]
会有多个重复的信息,
# ‘tid’: 3一样的话,转变成{‘tid’: 3, ‘name’: ‘王老师’, ‘titles’: [‘动漫’,‘软件’]}
# 怎么转变,这就涉及到判断了
#通过下面的代码,把同一个老师的任课班级,放在一个字典里面
result = {}
for row in teacher_list:
tid = row['tid']
if tid in result:
result[tid]['titles'].append(row['title'])
else:
result[tid] = {'tid':row['tid'],'name':row['name'],'titles':[row['title'],]}
urls.py
path('teachers/', views.teachers),
html页面下
alert(1)页面出现一个弹窗提示
2.添加
teacher.html添加跳转
增加页面 add_teacher.html
添加老师,需要获取到全部的班级信息,同时一个老师可能会任教多个班级,所以要在 下拉框增加这个,multiple,(下拉框可以多选)
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>添加老师</h2>
<form method="post" action="/add_teacher/">
<p><input type="text" name="name" placeholder="老师姓名"></p>
<p>
<select multiple size="10" name="class_ids"> {# multiple,下拉框可以多选 #}
{% for item in class_list %}
<option value="{{ item.id }}" >{{ item.title }}</option>
{% endfor %}
</select>
</p><input type="submit" value="提交">
</form>
</body>
</html>
views.py
添加函数
def add_teacher(request):
if request.method == "GET":
class_list = sqlheper.get_list('select id,title from class',[])
return render(request,'add_teachet.html',{'class_list':class_list})
else:
name = request.POST.get('name')
#老师表中增加一条数据,并返回老师的ID
teacher_id = sqlheper.create('insert into teacher(name) value (%s)',[name,])
print(teacher_id)
#老师和班级关系表中插入数据
#方老师 ['2', '3']
#获取当前添加的老师ID,
#2
#3
#先查询老师的老师ID,然后插入数据
class_ids = request.POST.getlist('class_ids')
print('0')
# 循环插入,但是多次操作数据库,效率底下,这个操作可以一次做完
#多次链接多次提交,,可
# for cls_id in class_ids:
# sqlheper.add_list('insert into teacher2class(teacher_id,class_id) value (%s,%s)',[teacher_id,cls_id,])
#一次链接,多次提交
# obj = sqlheper.SqlHelper()
# for cls_id in class_ids:
# obj.modify('insert into teacher2class(teacher_id,class_id) value (%s,%s)',[teacher_id,cls_id,])
# obj.close()
#一次链接,一次提交
data_list = []
for cls_id in class_ids:
temp = (teacher_id, cls_id,)
data_list.append(temp) #data_list.append = (temp) 别在中间加了个等于号,查问题查了半个钟,靠靠靠
obj = sqlheper.SqlHelper()
obj.multiple_modify('insert into teacher2class(teacher_id,class_id) value (%s,%s)',data_list)
obj.close()
return redirect('/teachers/')
为增加系统的运行速率,一般情况下进行一次对数据库的操作时,是一次连接一次操作,效率低下。
上面#一次链接,一次提交,功能,需要对数据库的操作文件进行修改。
sqlheper.py
增加一个类。把对数据库的操作封装在一个类里面
class SqlHelper(object):
def __init__(self): #初始化
#读取配置文件
self.connect()
def connect(self): #这是一个方法,先链接,链接上之后
self.conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='root', db='pydata', charset='utf8')
self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor)
# 拿一个列表
def get_list(self,sql,args):
self.cursor.execute(sql, args)
result = self.cursor.fetchall()
return result
# 拿一个值
def get_one(self,sql,args):
self.cursor.execute(sql, args)
result = self.cursor.fetchone()
return result
# 修改,删除,没有返回值
def modify(self,sql,args):
self.cursor.execute(sql, args)
self.conn.commit()
#传入的是元组,添加
def multiple_modify(self,sql,args):
#self.cursor.executemany('insert into db(in,name) vlause(%s,%s)', [(1,'alex'),(2,'erxt')]) #传入的是元组,执行数据库的是两条添加语句
self.cursor.executemany(sql, args)
self.conn.commit()
# 添加并且拿返回值
def create(self,sql,args):
self.cursor.execute(sql, args)
self.conn.commit()
return self.cursor.lastrowid
#关闭数据库链接
def close(self):
self.cursor.close()
self.conn.close()
#这样就在一个类里面,封装了全部的操作
3.编辑
teacher.html
views.py
增加函数
在点击编辑连接的时候,会通过GET请求发送teacher_id到后台,即nid,
获取到nid后可到老师和班级关系表,查找出老师当前任教的班级,返回到前端,前端设置选择默认值
#编辑老师信息
def edit_teacher(request):
if request.method == 'GET':
nid = request.GET.get('nid')
obj = sqlheper.SqlHelper() #先创建对象
teacher_info = obj.get_one('select id,name from teacher where id=%s',[nid,]) #获取到当前老师的信息
class_id_list = obj.get_list('select class_id from teacher2class where teacher_id=%s',[nid,]) #拿到当前老师所有的班级id
class_list = obj.get_list('select id,title from class ', []) #获取全部的班级信息
obj.close() #关闭链接
print('当前老师信息:',teacher_info)
print('当前老师任教信息:',class_id_list)
print('所有的班级信息:', class_list)
# 把默认的教师任教的班级ID,转换成数组,到前端做判断
temp = []
for i in class_id_list:
temp.append(i['class_id'])
return render(request,'edit_teacher.html',{
'teacher_info':teacher_info,
'class_id_list': temp,
'class_list': class_list,
})
else:
nid=request.GET.get('nid')
name = request.POST.get('name')
class_ids = request.POST.getlist('class_ids')
obj = sqlheper.SqlHelper() #大意错误,时刻警惕,缺少个()
# print(nid,name,class_ids)
# print('老师名字:',name)
#更新老师表
obj.modify('update teacher set name=%s where id=%s',[name,nid])
#更新老师和班级关系表,
# (方案一,先把老师和班级对应的关系先删除,后添加)
obj.modify('delete from teacher2class where teacher_id=%s',[nid,]) #删除
#添加
data_list = []
for cls_id in class_ids:
temp = (nid, cls_id,)
data_list.append(temp) #data_list.append = (temp) 别在中间加了个等于号,查问题查了半个钟,靠靠靠
obj = sqlheper.SqlHelper()
obj.multiple_modify('insert into teacher2class(teacher_id,class_id) value (%s,%s)',data_list)
obj.close()
return redirect('/teachers/')
# (方案二,先去和老师班级关系表做对比,后操作)
edit_teacher.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>老师列表</h1>
<a href="/add_teacher/">添加老师</a>
<div>
</div>
<table border="1" >
<thead>
<tr>
<th>老师ID</th>
<th>老师名称名称</th>
<th>任教班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for msg in teacher_list %}
<tr>
<td>{{ msg.tid }}</td>
<td>{{ msg.name }}</td>
<td>{% for foo in msg.titles %}
<span style="display: inline-block;padding: 5px;border: 1px solid red;">{{ foo }}</span>
{% endfor %}
</td>
<td>
<a href="/edit_teacher/?nid={{ msg.tid }}">编辑</a>
<a >对话框编辑</a>|
<a>删除</a>
<a > 对话框删除 </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
,先把老师和班级对应的关系先删除,后添加。
.
.
●模态对话框的添加老师
teacher.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.hide{
display: none;
}
.shadow{
/*相对于窗口*/
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
background-color: black;
opacity: 0.4;
z-index: 999;
}
.add_modal{
/*相对于窗口*/
position: fixed;
left: 50%;
top:50%;
width: 400px;
height: 300px;
z-index: 1000;
background-color: white;
margin-left: -200px; {#左移200像素 #}
margin-top: -200px;
}
.loading{
position: fixed;
width: 120px;
height: 120px;
left: 50%;
top: 50%;
margin-left: -60px;
margin-top: -60px;
background-image:url("/static/images/timg (1).gif");
}
</style>
</head>
<body>
<h1>老师列表</h1>
<a href="/add_teacher/">添加老师</a>
<a id="btnAdd">对话框添加老师</a>
<div>
</div>
<table border="1" >
<thead>
<tr>
<th>老师ID</th>
<th>老师名称名称</th>
<th>任教班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for msg in teacher_list %}
<tr>
<td>{{ msg.tid }}</td>
<td>{{ msg.name }}</td>
<td>{% for foo in msg.titles %}
<span style="display: inline-block;padding: 5px;border: 1px solid red;">{{ foo }}</span>
{% endfor %}
</td>
<td>
<a href="/edit_teacher/?nid={{ msg.tid }}">编辑</a>
<a class="btnEdit" class_Ids="msg.titles">对话框编辑</a>|
<a href="/del_teacher/?nid={{ msg.tid }}">删除</a>
<a > 对话框删除 </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{#遮罩层#}
<div id="shadow" class="shadow hide"></div>
{#添加模态框#}
<div id="addModal" class="add_modal hide" >
<h3>添加老师</h3>
<p>老师姓名:
<input type="text" name="name" id="editName">
</p>
<p>
<P>任教班级:</P>
<select id="classIds" multiple size="10" ></select>
</p>
<a id="addSubimt">提交</a>
</div>
{#编辑模态框#}
<div id="etidModal" class="edit_modal hide" >
<h3>编辑老师</h3>
<p>老师姓名:
<input type="text" name="name" id="addName">
</p>
<p>
<P>任教班级:</P>
<select id="classIds" multiple size="10" ></select>
</p>
<a id="addSubimt">提交</a>
</div>
{# 搞个加载框 #}
<div id="loading" class="loading hide"></div>
<script src="/static/jquery-2.1.4.min.js"></script>
<script>
$(function() {
{# 绑定事件#}
{# 如果是按照之前那样做的话代码量就太多重复的了,#}
bindAdd();
binAddSubimt();
btnEdit();
});
//显示添加老师模态框及发送添加请求
function bindAdd() {
{#绑定事件放到这里的函数来#}
$('#btnAdd').click(function () {
$('#shadow,#loading').removeClass('hide');
/*
* 发送ajax请求,获取所有班级信息
* 在classIds下拉框中生成option*/
$.ajax({
url:'/get_all_class/',
type:'GET',
dataType:'JSON',
success:function (arg) {
/*获取到的数据是这样的,需要循环
arg=[
{id:1,title:xx},
{id:1,title:xx},
{id:1,title:xx},
]
*/
//console.log(arg);
//将所有的数据添加到select,option
$.each(arg,function (i,row) { //这里的i是索引,row才是上面的字典
var tag = document.createElement('option'); //生成标签,创建option的标签,document方式
tag.innerHTML = row.title; //在option标签内容里面写了个row.title.
tag.setAttribute('value',row.id); //属性里面写了'value',row.id
$('#classIds').append(tag); //找到div里面id为classIds的下拉框
});
$('#loading').addClass('hide'); //服务端设置延时发送数据,模拟数据加载,前端在数据到达前是先显示加载图标,
$('#addModal').removeClass('hide'); //数据到达后,隐藏加载图片的div,显示添加页面
}
})
})
}
{#添加提交数据函数#}
function binAddSubimt() {
$('#addSubimt').click(function () {
var name = $('#addName').val();
var class_id_list = $('#classIds').val(); //这里不用担心val(),如果是单选val拿到的就是单个值,如果是多选拿到的就是多个值
// console.log(name,class_id_list);
$.ajax({
url:'/modal_add_teacher/',
type:'POST', //定个小规则,一般要后台拿上面用get,要是发数据到后台用POST,
data:{'name':name,'class_id_list':class_id_list}, //传的是列表,要加上下面的语句
dataType:'JSON',
traditional:true, //表示为上面data的数据不做特殊处理, 所以data里面有列表的话,都要加上这句话 //如果提交的数据的值有列表,则需要添加此属性
success:function (arg) {
if (arg.status){
location.reload();
} else {
alert(arg.message);
} } }) })}
</script>
</body>
</html>
urls.py
path('get_all_class/', views.get_all_class),
path('modal_add_teacher/', views.modal_add_teacher),
views.py
#模态对话框,获取信息
def get_all_class(request):
time.sleep(1)
obj = sqlheper.SqlHelper()
class_list = obj.get_list('select id,title from class', [])
obj.close()
# return HttpResponse(json.dumps(class_list))
return HttpResponse(json.dumps(class_list))
#模态对话框添加,执行添加
def modal_add_teacher(request):
ret = {'status':True,'message':None}
try:
name = request.POST.get('name')
class_id_list = request.POST.getlist('class_id_list')
teacher_id = sqlheper.create('insert into teacher(name) value (%s)', [name, ])
# class_ids = request.POST.getlist('class_ids')
data_list = []
for cls_id in class_id_list:
temp = (teacher_id, cls_id,)
data_list.append(temp) # data_list.append = (temp) 别在中间加了个等于号,查问题查了半个钟,靠靠靠
obj = sqlheper.SqlHelper()
obj.multiple_modify('insert into teacher2class(teacher_id,class_id) value (%s,%s)', data_list)
obj.close()
except Exception as e:
ret['status']=False
ret['message']="处理失败"
return HttpResponse(json.dumps(ret))