Django之学员管理

  实现-------在前端页面提交的数据,后端可直接写入数据库。在页面实现操作数据库的增删改查。

  数据表设计:(三个角色四张表)

    班级表:

      id  title

      1   花果山国小一年级

      2  水帘洞小学二年级

   

    学生表:

      id  name  班级ID (FK)

      1  抠脚大汉  1

      2  一杯倒    2

    老师表:

      id  name

      1  George  

      2  BJ

      3  CF

    

    老师班级关系表:

      id  老师ID  班级ID 

      1    1    1

      2    2    1

      3    2    2

  在Django之初里,我们将几乎所有的url所对应的功能函数都写在里url文件里。这样是不好看也不方便管理的。

  所以,我们会创建很多文件夹,每个文件夹里存放针对某一功能的代码。便于管理代码。

  代码在APP的views.py里。

  在url中,将APP的导入即可。这样url就依旧可以找到相应的函数。  

from APPS import views

  在页面拿到数据库表的数据:

    前端classes.html的MK1呈现:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>classes</title>
</head>
<body>
<h1>classes_list</h1>
<table>
<thead>
<tr>
<th>ID</th>
<th>班级名称</th>
</tr>
</thead>
<tbody>
{% for item in class_lsit %}
<tr>
<td>{{ item.cid }}</td>
<td>{{ item.caption }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>

    后端的views.py 中的classes函数的代码呈现:

 def classes(request):
"""
链接数据库
:param request: 用户请求的相关的所有信息(对象)
:return:
"""
import pymysql
conn = pymysql.connect(host="127.0.0.1",port=3306,user='root',passwd='劳资的数据库密码你也想知道',db='劳资的数据库名字',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) #改为字典
cursor.execute("select cid,caption from classes")
class_list = cursor.fetchall()
cursor.close()
conn.close() return render(request, "classes.html",{"class_lsit":class_list})

   测试结果:如愿拿到了。

  

  总体进阶:MK2

    在classes.html页面,可以在页面直接添加数据并存到数据库保存。

    这样的话,就需要有一个add_class啦。

    MK2.1

    classes.html页面加一个div标签

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>classes</title>
</head>
<body>
<h1>classes_list</h1>
<div>
10 <a href="/add_class/">添加</a>
11 </div>
<table>
<thead>
<tr>
<th>ID</th>
<th>班级名称</th>
</tr>
</thead>
<tbody>
{% for item in class_lsit %}
<tr>
<td>{{ item.cid }}</td>
<td>{{ item.caption }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>

  加add_class.html 页面:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>add_class</title>
</head>
<body>
<h1>添加班级</h1>
<form action="">
<p>班级名称:<input type="text" placeholder="请输入内容"/></p>
<input type="submit" value="提交">
</form>
</body>
</html>

  views.py中的add_class函数:

 def add_class(request):
"""
前端添加数据到数据库
:param request:
:return:
"""
return render(request,'add_class.html')

  MK2.5

  现在应该是在add_class页面中添加要提交的数据,点击submit,数据会给数据库,数据库刷新并返回结果。

  而add_class页面也应该再有以一次post请求。完成跳转去classes.html页面。

  add_class函数的实现: 

 def add_class(request):
"""
前端添加数据到数据库
:param request:
:return:
"""
if request.method == "GET":
return render(request,"add_class.html")
else:
print(request.POST)
v = request.POST.get("caption")
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='XXXXx', db='XXXXx',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("insert into classes(caption) values(%s)",[v,]) #插入操作
conn.commit() #提交数据
cursor.close()
conn.close()
return redirect("/classes/")

  add_class.html 页面

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>add_class</title>
</head>
<body>
<h1>添加班级</h1>
<form method="POST" action="/add_class/">
<p>班级名称:<input type="text" name="caption" placeholder="请输入内容"/></p>
<input type="submit" value="提交">
</form>
</body>
</html>

  MK3:删除。在每行数据的后面加一个删除操作按钮。使其可以去数据库删除掉对应的数据。并返回删除后刷新的结果,跳转到classes页面。

  classes.html 页面的删除按钮的添加:

    在删除过程中,设法使其知道要删除的是哪一行的数据。通过id实现。

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>classes</title>
</head>
<body>
<h1>classes_list</h1>
<div>
<a href="/add_class/">添加</a>
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>班级名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in class_lsit %}
<tr>
<td>{{ item.cid }}</td>
<td>{{ item.caption }}</td>
<td><a href="/del_class/?nid={{ item.cid }}">删除</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>

  del_class函数:

 def del_class(request):
"""
删除操作
:param request:
:return:
"""
#那删除操作的nid。
nid = request.GET.get("nid")
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='XXXx', db='XXXXx', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("delete from classes where cid=%s", [nid,])
conn.commit()
cursor.close()
conn.close()
return redirect('/classes/')

  改编辑了:

  MK4:

     问题,在后端的编辑的过程中,由于是基于Http协议的请求,所以前端页面在拿到要编辑的数据后,在在编辑完提交时,数据库不知道提交的是哪一行的数据。

    所以,前端需要连同数据行的id也一并拿走,在提交是,也一并返回,好告知数据库是哪一行的数据。

  解决方案一:

  edit_class函数:

 def edit_class(request):
"""
编辑班级
:param request:
:return:
"""
if request.method == "GET":
nid = request.GET.get('nid')
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='XXXX', db='XXXXXst', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("select cid,caption from classes where cid=%s", [nid, ])
result = cursor.fetchone()
cursor.close()
conn.close()
print(result)
return render(request,"edit_class.html",{"result":result})
else:
nid = request.POST.get("cid")
caption = request.POST.get("caption")

  edit_class.html

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>edit_class</title>
</head>
<body>
<h1>编辑班级</h1>
<form method="POST" action="/edit_class/">
<input style="display: none" name="cid" value="{{ result.cid }}">
<p>班级名称:<input type="text" name="caption" value="{{ result.caption }}" placeholder="请输入替换数据"></p>
<input type="submit" value="submit">
</form>
</body>
</html>

    方案二:区别在前端页面的不通,在与如何隐藏不该用户见到的数据行id。

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>edit_class</title>
</head>
<body>
<h1>编辑班级</h1>
<form method="POST" action="/edit_class/?nid={{ result.cid }}">
<p>班级名称:<input type="text" name="caption" value="{{ result.caption }}" placeholder="请输入替换数据"></p>
<input type="submit" value="submit">
</form>
</body>
</html>

    在views函数中,request也变了。

 def edit_class(request):
"""
编辑班级
:param request:
:return:
"""
if request.method == "GET":
nid = request.GET.get('nid')
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='redhat', db='GeorgeTest', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("select cid,caption from classes where cid=%s", [nid, ])
result = cursor.fetchone()
cursor.close()
conn.close()
print(result)
return render(request,"edit_class.html",{"result":result})
else:
nid = request.GET.get("nid") #这里与方案一的不一样
caption = request.POST.get("caption")
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='redhat', db='GeorgeTest',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("update classes set caption=%s where cid=%s",[caption,nid,])
conn.commit()
cursor.close()
conn.close()
return redirect("/classes/")

----------------以上是班级的增删改操作。----------------

 老师的操作同理。就直接上最终版本啦。

teacher.html 页面代码:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>teacher</title>
</head>
<body>
<h1>老师表</h1>
<div>
<a href="/add_teacher/">添加</a>
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>name</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for foo in teacher_list %}
<tr>
<td>{{ foo.id }}</td>
<td>{{ foo.name }}</td>
<td>
<a href="/del_teacher/?nid={{ foo.id }}">删除</a>
|
<a href="/edit_teacher/?nid={{ foo.id }}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>

add_teacher.html 页面代码:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>add_teacher</title>
</head>
<body>
<h1>添加老师表</h1>
<form method="POST" action="/add_teacher/">
<p>老师添加:<input type="text" name="name" placeholder="添加老师"/></p>
<input type="submit" value="submit">
</form>
</body>
</html>

edit_teacher.html 页面代码:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>edit_teacher</title>
</head>
<body>
<h1>编辑老师</h1>
<form method="POST" action="/edit_teacher/?nid={{ result.id }}">
<p>老师名称:<input type="text" name="name" value="{{ result.name }}" placeholder="请输入替换数据"></p>
<input type="submit" value="submit">
</form>
</body>
</html>

teacher相关函数功能代码:

 def teacher(request):
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='redhat', db='GeorgeTest', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("select id,name from user")
teacher_list = cursor.fetchall()
cursor.close()
conn.close()
return render(request,"teacher.html",{"teacher_list":teacher_list}) def add_teacher(request):
if request.method == "GET":
return render(request,"add_teacher.html")
else:
print(request.POST)
v = request.POST.get("caption")
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='redhat', db='GeorgeTest',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("insert into user(name) values(%s,)", [v,])
conn.commit()
cursor.close()
conn.close()
return redirect("/teacher/") def del_teacher(request):
"""
删除操作
:param request:
:return:
"""
# 那删除操作的nid。
nid = request.GET.get("id")
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='redhat', db='GeorgeTest', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("delete from user where id=%s", [nid, ])
conn.commit()
cursor.close()
conn.close()
return redirect('/teacher/') def edit_teacher(request):
"""
编辑老师
:param request:
:return:
"""
if request.method == "GET":
nid = request.GET.get('nid')
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='redhat', db='GeorgeTest',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("select id,name from user where id=%s", [nid, ])
result = cursor.fetchone()
cursor.close()
conn.close()
print(result)
return render(request, "edit_teacher.html", {"result": result})
else:
id = request.GET.get("nid")
name = request.POST.get("name")
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='redhat', db='GeorgeTest',
charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("update user set name=%s where id=%s",[name,id,])
conn.commit()
cursor.close()
conn.close()
return redirect("/teacher/") # Create your views here.

----------------------------- 以上就是老师表的全部代码 -------------------

学生表,这里的学生表就要出现一对多的关系了。一个班级对应多个学生。

  学生表这里讲用到模态对话框和Ajax的知识。

  获取学生表数据:

 def students(request):
"""
学生列表
:param request:
:return:
"""
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='redhat', db='GeorgeTest', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("select student.id,student.name,class.title from student left JOIN class on student.class_id = class.id")
students_list = cursor.fetchall()
cursor.close()
conn.close() return render(request,"students.html",{"students_list":students_list})

  students.html 页面代码:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>students</title>
</head>
<body>
<h1>students_list</h1>
<div>
<a href="/add_students/">添加</a>
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>学生姓名</th>
<th>所属班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in students_list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.title }}</td>
<td>
<a href="/del_students/?nid={{ item.id }}">删除</a>
|
<a href="/edit_students/?nid={{ item.id }}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>

  创建学生信息:也就是添加学生。

  和删除学生信息,删除学生信息和删除班级的一样。

 def add_students(request):
if request.method == "GET":
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='redhat', db='GeorgeTest', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select id,title from classes")
class_list = cursor.fetchall()
cursor.close()
conn.close() return render(request, 'add_students.html', {'class_list': class_list})
else:
name = request.POST.get('name') #获取POST里的name,也就是前端输入的name
class_id = request.POST.get('class_id') #获取班级表,班级的id
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='redhat', db='GeorgeTest', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("insert into student(name,class_id) values(%s,%s)", [name, class_id, ])
conn.commit()
cursor.close()
conn.close()
return redirect('/students/') def del_students(request):
nid = request.GET.get("nid")
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='redhat', db='GeorgeTest', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("delete from students where id=%s", [nid,])
conn.commit()
cursor.close()
conn.close()
return redirect('/students/')

  add_students.html 页面代码:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>add_students</title>
</head>
<body>
<h1>添加学生</h1>
<form method="POST" action="/add_students/">
<p>学生姓名<input type="text" name="name" /></p>
<p>
所属班级
<select name="class_id">
{% for row in class_list %}
<option value="{{ row.id }}">{{ row.title }}</option>
{% endfor %}
</select>
</p>
<input type="submit" value="提交" />
</form>
</body>
</html>

  接下来是编辑学生表。

  可是,大哥们,劳资频繁的每个函数都要连一下数据库。怎的很烦。我要改一下玩法。将数据库的剔除,单独放在一个文件夹里。用的时候直接导入。

  等到后期,会在每个APP里见model。model里写ORM,就更方便了,但是现在慢慢来!

  创建一个utils,里边写一个sqlheper.py,这个py文件,放pymysql的操作。

  sqlheper.py

import pymysql

def get_list(sql,args):
"""
获取列表信息
:param sql: pymysql语句
:param args:
:return:
"""
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='redhat', db='GeorgeTest', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute(sql,args)
result = cursor.fetchall()
cursor.close()
conn.close()
return result def get_one(sql,args):
"""
   获取一条数据信息
:param sql: pymysql语句
:param args:
:return:
"""
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='redhat', db='GeorgeTest', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute(sql,args)
result = cursor.fetchone()
cursor.close()
conn.close()
return result def modify(sql,args):
"""
更新,删除,修改
:param sql: pymysql语句
:param args:
:return:
"""
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='redhat', db='GeorgeTest', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute(sql,args)
conn.commit()
cursor.close()
conn.close()

  编辑学生表的函数:edit_students:

 from utils import sqlheper
def edit_student(request):
if request.method == "GET":
nid = request.GET.get('nid')
class_list = sqlheper.get_list("select id,title from class",[])
# 获取所有班级 sqlheper.get_list()
current_student_info = sqlheper.get_one('select id,name,class_id from student where id=%s',[nid,])
# 获取一条数据信息 sqlheper.get_one()
return render(request,'edit_student.html',{'class_list': class_list,'current_student_info':current_student_info})
else:
nid = request.GET.get('nid')
name = request.POST.get('name')
class_id = request.POST.get('class_id')
sqlheper.modify('update student set name=%s,class_id=%s where id=%s',[name,class_id,nid,])
return redirect('/students/')

  edit_students.html 页面代码:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>edit_students</title>
</head>
<body>
<h1>编辑学生</h1>
<form method="POST" action="/edit_students/?nid={{ current_student_info.id }}"> <p>学生姓名<input type="text" name="name" value="{{ current_student_info.name }}" /></p>
<p>
所属班级
<select name="class_id">
<!-- 循环所有的班级 -->
{% for row in class_list %}
<!-- 如果是当前学生所在班级,则默认选中 -->
{% if row.id == current_student_info.class_id %}
<option selected value="{{ row.id }}">{{ row.title }}</option>
{% else %}
<option value="{{ row.id }}">{{ row.title }}</option>
{% endif %} {% endfor %}
</select>
</p>
<input type="submit" value="提交" />
</form>
</body>
</html>

  对之前的内容优化,其中:

    班级的添加,对空字符串没有识别。所以,如果在添加页面,不添加数据,直接提交是可行的。

    但是,这样不符合设定。对此进行优化。

    优化如下:

    add_classes 函数代码:

 def add_class(request):
"""
前端添加数据到数据库
:param request:
:return:
"""
if request.method == "GET":
return render(request,"add_class.html")
else:
print(request.POST)
v = request.POST.get("caption")
if len(v)>0:
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='redhat', db='GeorgeTest',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 改为字典
cursor.execute("insert into classes(caption) values(%s)",[v,])
conn.commit()
cursor.close()
conn.close()
return redirect("/classes/")
else:
return render(request,"add_class.html",{"msg":"班级名称不能为空"})

add_classes.html 页面代码:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>add_class</title>
</head>
<body>
<h1>添加班级</h1>
<form method="POST" action="/add_class/">
<p>班级名称:<input type="text" name="caption" placeholder="请输入内容"/></p>
<input type="submit" value="提交">{{ msg }}
</form>
</body>
</html>

  以后再views中,对用户提交的数据进行判断,要用form组件。

   模态对话框:

    就是在前端做两层装饰,第一层是遮罩层,第二层是内容层(对话框)。

    针对班级管理,进行进一步的优化,用模态对话框的知识。

    班级管理:

      -添加操作。用模态对话框实现。

          模态对话框有两层,就写两个div。

          但要在前端的页面里加装饰,在head里加。

          .shadow加在遮罩层。

          .modal 加在内容层。

          模态对话框加在classes.html 里。

          用到了form表单提交,form表提交会导致页面刷新。 

          页面一涮新,模态对话框就不保留了。

classes.html 页面:

 <!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.cid }}</td>
<td>{{ item.caption }}</td>
<td>
<a href="/del_class/?nid={{ item.cid }}">删除</a>
|
<a href="/edit_class/?nid={{ item.cid }}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table> <div id="shadow" class="shadow hide"></div>
<div id="modal" class="modal hide">
<form method="POST" action="modal_add_classes" >
<p>
<input type="text" name="title" placeholder="班级名称">
</p>
<input type="submit" name="submit">
</form> </div>
<script>
function showModal() {
document.getElementById("shadow").classList.remove("hide"); #找到遮罩层,并去挑遮罩层
document.getElementById("modal").classList.remove("hide"); }
</script>
</body>
</html>

模态对话框添加代码:

 def modal_add_classes(request):
#获取前端的title
title = request.POST.get('title')
if len(title) > 0:
sqlheper.modify('insert into class(title) values(%s)',[title,])
# return HttpResponse('ok')
return redirect('/classes/')
elif title == "*?#.":
pass
else:
return HttpResponse('班级标题不能为空')

  对话框提交数据,不建议使用form表单。

   

 在Django中的Ajax的应用:数据提交,建议使用。

    Ajax,在页面不刷新的情况下,默默的向后台提交数据。这里要引入jQuery。

  基于Ajax,创建学员管理的班级:

      给前端的提交按键,绑定事件,onclick="AjaxSend();"

      在script里的function函数里加AjaxSend(),这时在提交时,就是Ajax提交。$.ajax()

      要注意:Ajax提交的数据有指定:

            数据提交到哪里,要指定:url     数据提交到指定的url中

            数据提交的方法,要指定:type   以什么方法提交数据

            数据提交的数据,要指定:data   要提交的数据,字典存储  data:{"title":"XXXXX"}

            定义success:function(data){

              } :作用是,在url,type,data发完数据后,ajax会等。等到服务端处理完了,返回数据了,这个success会自动调用。

                 function里的data是服务端返回的值。

            数据提交成功后,要干嘛:

            数据提交失败后,要干嘛:

     

      ajax提交不能实现跳转,是因为ajax本质上只返回字符串。要想实现跳转,只能自己写JS进行跳转。

=============== Ajax添加 ===============

 <!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.cid }}</td>
<td>{{ item.caption }}</td>
<td>
<a href="/del_class/?nid={{ item.cid }}">删除</a>
|
<a href="/edit_class/?nid={{ item.cid }}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table> <div id="shadow" class="shadow hide"></div>
<div id="modal" class="modal hide">
<form method="POST" action="modal_add_classes" >
<p>
<input id="title" type="text" name="title" placeholder="班级名称">
</p>
<input type="button" name="submit" onclick="AjaxSend();"/>
</form> </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 AjaxSend() {
$.ajax({
url:'/modal_add_classes/',
type:'POST',
data:{"title":$("#title").val()}, //拿到全段输入的值
success:function (data) {
//当服务端处理完成后,返回数据时,该函数自动调用
//data是服务端返回的值
console.log(data);
if(data=="ok"){
alert('添加成功');
}else {
alert('添加失败');
}
}
})
}
</script>
</body>
</html>

  提交的解决方案:

    在提交的后面加一个span标签。 

<span id="errormsg"></span>

  效果:classes.html  

 <!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.cid }}</td>
<td>{{ item.caption }}</td>
<td>
<a href="/del_class/?nid={{ item.cid }}">删除</a>
|
<a href="/edit_class/?nid={{ item.cid }}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table> <div id="shadow" class="shadow hide"></div>
<div id="modal" class="modal hide">
<form method="POST" action="modal_add_classes" >
<p>
<input id="title" type="text" name="title" placeholder="班级名称">
</p>
<input type="button" name="submit" onclick="AjaxSend();"/><span id="errormsg"></span>
<input type="button" name="取消" onclick="cancleModal();"/>
</form> </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')
}
function AjaxSend() {
$.ajax({
url:'/modal_add_classes/',
type:'POST',
data:{"title":$("#title").val()}, //拿到全段输入的值
success:function (data) {
//当服务端处理完成后,返回数据时,该函数自动调用
//data是服务端返回的值
console.log(data);
if(data=="ok"){
location.href='/classes/'; //指定提交成功后跳转到哪里
}else {
$('#errormsg').text(data);
}
}
})
}
</script>
</body>
</html>

  modal_add_classes:

 def modal_add_classes(request):
#获取前端的title
title = request.POST.get('title')
if len(title) > 0:
sqlheper.modify('insert into class(title) values(%s)',[title,])
return HttpResponse('ok')
# return redirect('/classes/')
elif title == "*?#.":
pass
else:
return HttpResponse('班级标题不能为空')

============  班级的编辑操作,用ajax实现:单表的  =============

     技巧,对于a标签的事件,跳转的问题,可以绑定再绑定一个事件,跳转到别的地方。

      在a标签中的onclick事件中加return。

      在function modelEdit(){

        alert(123);

        return false

      }

       在return 这里是关键,事件优先执行onclick,执行完后执行href,返回return,在function中将return的返回值设为False,就不会执行href里要跳转的url。

        改为True,就会进行跳转。

        这个功能用在form表单里。

      在点击编辑后,需要将要编辑的内容放在编辑框,需要做的方法是,将获取当前点击的标签,以及他上一级的标签。

        其次是标签父标签,再找其上方标签。

后端代码:

 def modal_edit_classes(request):
ret = {"status":True,"message":None}
try:
nid = request.POST.get("nid") # 拿id
content = request.POST.get("content") #拿内容
sqlheper.modify("update class set title=%s where id=%s",[content,nid,])
except Exception as e:
ret['status'] = False
ret['message'] = "处理异常"
return HttpResponse(json.dumps(ret)) #json将数据转成字符串,在发给前端

前端代码:

 <!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.cid }}</td>
<td>{{ item.caption }}</td>
<td>
<a href="/del_class/?nid={{ item.cid }}">删除</a>
|
<a onclick="modelEdit();">对话框删除</a>
|
<a href="/edit_class/?nid={{ item.cid }}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table> <div id="shadow" class="shadow hide"></div>
<div id="modal" class="modal hide">
<form method="POST" action="modal_add_classes" >
<p>
<input id="title" type="text" name="title" placeholder="班级名称">
</p>
<input type="button" name="submit" onclick="AjaxSend();"/><span id="errormsg"></span>
<input type="button" name="取消" onclick="cancleModal();"/>
</form>
</div> <div id="editModel" class="modal hide">
<h3>编辑框</h3>
<p>
<input id="editId" type="text" name="id" style="display: none" />
<input id="editTitle" type="text" name="title" />
</p>
<input type="button" value="提交" onclick="editAjaxSend();" /><span id="errormsg"></span>
<input type="button" value="取消" 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('eidtModal').classList.add('hide')
} function AjaxSend() {
$.ajax({
url:'/modal_add_classes/',
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();
var content = $(row[0]).text();
$('editTitle').val(content); var contentId = $(row[1].text());
$('#editId').var(contentId); } function editAjaxSend() {
var nid = $('#editID').val();
var content = $('#editTitle').val();
console.log(nid,content);
$.ajax({
url:'/modal_edit_classes/',
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>

================== ajax 学生表,一对多,添加 ================== 

  绑定事件,都是基于jQuery。

  jQuery也可以阻止默认事件的发生。

 <script>
//绑定事件。
$(function () {
$("#modal_add_students").click(function () {
alert(123);
return false; #阻止默认事件
})
})
</script>

后端代码:

 def modal_add_students(request):
ret = {"status":True,"message":None} try:
name = request.POST.get("name")
classes_id = request.POST.get("classes_id")
sqlheper.modify('insert into students(name,classes_id) values(%s,%s)',[name,classes_id,])
except Exception as e:
ret['status'] = False
ret['message'] = str(e) return HttpResponse(json.dumps(ret))

前端代码:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>students</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;
}
.add-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>students_list</h1>
<div>
<a href="/add_students/">添加</a>
|
<a onclick="modal_add_students">对话框添加</a>
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>学生姓名</th>
<th>所属班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in students_list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.title }}</td>
<td>
<a href="/del_students/?nid={{ item.id }}">删除</a>
|
<a href="/edit_students/?nid={{ item.id }}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table> <div id="shadow" class="shadow hide"></div>
<div id="addModal" class="add-modal hide"></div> <p>
Name:<input id="addName" type="text" name="name" placeholder="Name">
</p>
<p>
Classes:<input id="addClassesId" type="text" name="Classes" placeholder="Classes">
<select name="classesID" >
{% for row in classes_list %}
<option value="{{ row.id }}">{{ row.title }}</option>
{% endfor %} </select>
</p>
<input id="btnAdd" type="button" value="添加" />
<span id="addError" style="color: red;"></span> <script src="/static/jquery-1.12.4.js"></script>
<script>
//绑定事件。
$(function () {
$("#addModal").click(function () {
$("#shadow,#addModal").removeClass('hide');
}) $('#btnAdd').click(function () {
$.ajax({
url:"/modal_add_students/",
type:"POST",
data:{"name":$("#addName").val(),"classes_id":$("#addClassesId").val()},
success:function (arg) {
//回调函数,
//console.log(arg); //将数据发送给后台
arg = JSON.parse(arg);
if(arg.status){
location.reload();
}else{
$("#addError").text(arg.message);
}
}
})
})
})
</script>
</body>
</html>

--------- END ----------

  

Django之学员管理的更多相关文章

  1. Django之学员管理一

    Django之学员管理一 建表结构: #班级表class: id title 1 五年一班 2 五年二班 3 五年三班 4 五年四班 #学生表student: id name 班级ID(FK外键) 1 ...

  2. Django之学员管理三

    Django之学员管理三 web框架的本质: 本质是客户端和服务端的交互.用socket实现. socket客户端(浏览器) 2.发送ip和端口,http://www.baidu.com:80/ind ...

  3. Django之学员管理二

    Django之学员管理二 学生表的一对多的增删改查 views.py def students(request): #select students.sid,students.name,classes ...

  4. Django pymysql学员管理系统

    学员管理系统 项目规划阶段 项目背景 近年来老男孩教育的入学学员数量稳步快速增长,传统的excel统计管理学员信息的方式已经无法满足日渐增长的业务需求.因此公司急需一套方便易用的“学员管理系统”,来提 ...

  5. python学习笔记--Django入门四 管理站点--二

    接上一节  python学习笔记--Django入门四 管理站点 设置字段可选 编辑Book模块在email字段上加上blank=True,指定email字段为可选,代码如下: class Autho ...

  6. Django ORM 查询管理器

    Django ORM 查询管理器 ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言 ...

  7. Django + Ansible 主机管理(有源码)

    本文给大家介绍如何利用 Django + Ansible 进行 Web 项目管理.   Django介绍 一个可以使 Web 开发工作愉快并且高效的 Web 开发框架,能够以最小的代价构建和维护高质量 ...

  8. 如何在Django模型中管理并发性 orm select_for_update

    如何在Django模型中管理并发性 为单用户服务的桌面系统的日子已经过去了 - 网络应用程序现在正在为数百万用户提供服务,许多用户出现了广泛的新问题 - 并发问题. 在本文中,我将介绍在Django模 ...

  9. Django之后台管理一

    所有的网站都有一个管理后台来对所有的网站数据进行管理.那么Django的后台管理是如何进行的.在网页中输入http://127.0.0.1:8001/admin.得到如下的登录界面 在这里可以看到管理 ...

随机推荐

  1. servlet重定向到jsp后样式无法正常显示

    原因是在servlet中转发时css和图片的路径变成相对于这个servlet的相对路径而非相对于web项目的路径了. 解决办法:导入css样式和图片时把css写成动态绝对路径, 如用EL表达式表示: ...

  2. mybatis使用要点(2019.5.19)

    接口入参 只有一个参数,叫啥都没问题 有两个参数以上,需使用@Param,否则名字依次为0.1.2和param1.param2.param3 一般用#,防sql注入:偶尔用$,比如需要动态表名等 接口 ...

  3. iOS NSUserDefaults [setValue:forKey:] [setObject:forKey:] <Objc> setValue(_,forKey:) set(_,forKey) <Swift 3>

    前者其实是NSObject都可以调用的KVC方法,后者才是NSUserDefaults的实例方法: 这里参数的类型是nullable id,但是我建议你在传null的时候慎重考虑,否则你的应用就可能面 ...

  4. Include,Forward,sendRedirct的区别(转)

    三者在servlet中的最大区别是: Include和Forward:将当前请求转到另外一个JSP或者servlet处理. sendRedirct:将当前请求返回到浏览器,带上要redirect的UR ...

  5. 168 Excel Sheet Column Title Excel表列名称

    给定一个正整数,返回它在Excel表中相对应的列名称.示例:    1 -> A    2 -> B    3 -> C    ...    26 -> Z    27 -&g ...

  6. [转].NET MVC 分页以及增删查改

    本文转自:http://blog.csdn.net/sust2012/article/details/30761867 . 数据库操作,DAL 层: using System; using Syste ...

  7. SQL 多字段去重

    select articleID from (select aeUID, max(articleID) articleID from [article] group by aeUID) a conca ...

  8. 001.JS特效

    一.Js实现单行文本的滚动 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...

  9. JS学习-事件响应小结-简单的计算器

    <!DOCTYPE html> <html> <head> <title> 事件</title> <script type=" ...

  10. iOS 播放本地,网络视频

    /** *  创建媒体播放控制器MPMoviePlayerControlle 可以控制尺寸 * *  @return 媒体播放控制器 */ -(MPMoviePlayerController *)mo ...