一、建表
1、一对多
class Books(models.Model):
name = models.CharField(max_length=32)
cls = models.CharField(max_length=32)
class Publisher(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
address = models.CharField(max_length=32)
pub = models.ForeignKey(to='Books',to_field='id',on_delete=models.CASCADE) # 创建一对多
2、多对多
1)方式一(自定义关系表):
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32,db_index=True)
ip = models.GenericIPAddressField(protocol='ipv4',db_index=True)
port = models.IntegerField()
class Application(models.Model):
name = models.CharField(max_length=32)
class HostToApp(models.Model):
hobj = models.ForeignKey(to='Host',to_field='nid')
aobj = models.ForeignKey(to='Application',to_field='id')
# 在第三张表中直接添加数据
HostToApp.objects.create(hobj_id=1,aobj_id=3)
2)方式二(自动创建关系表):
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32,db_index=True)
ip = models.GenericIPAddressField(protocol='ipv4',db_index=True)
port = models.IntegerField()
class Application(models.Model):
name = models.CharField(max_length=32)
r = models.ManyToManyField('Host') # 自动创建第三张对应表
# 在第三张表中间接添加数据
obj = Application.objects.get(id=1)
obj.name
obj.r.add(1) # 在第三张表中增加了关系第一个Application对应第一个Host
obj.r.add(2,3,4) # 在第三张表中增加了关系第一个Application对应第二,三,四个Host
obj.r.add(*[1,2,3,4]) # 以列表形式添加多个关系
obj.r.remove(1)
obj.r.remove(2,3,4)
obj.r.remove(*[1,2,3])
obj.r.clear() # 关于Application1的对应关系全部清除
obj.set([3,5,7]) # 删除关于Application1的对应,重新加入这个
obj.r.all() # 获取所有相关的Host对象“列表”(QuerySet)
二、单表单数据的获取(三种方式)
1、在models下生成的单表有三种获取方式(在views中的操作):
方式一:
v1 = models.Books.objects.all()
# QuerySet
# [obj(id,name,cls),obj(id,name,cls),obj(id,name,cls)] 记录为对象
方式二:
v2 = models.Books.objects.values('id','name')
# QuerySet
# [{'id':1,'name':'C++'},{'id':2,'name':'English'}] 记录为字典
方式三:
v3 = models.Books.objects.values_list('id','cls')
# QuerySet
# [(1,编程),(2,语言),(3,社会)] 记录为集合
2、示例代码
models中的代码:

1 from django.db import models 2 3 # Create your models here. 4 5 class Books(models.Model): 6 name = models.CharField(max_length=32) 7 cls = models.CharField(max_length=32)
注:在数据库中插入Books表,并在其插入三条数据
id | name | cls |
1 | C++ | 编程 |
2 | English | 语言 |
3 | Social | 社会 |
views中的代码:

1 def BooksInfo(req): 2 v1 = models.Books.objects.all() 3 # QuerySet 4 # [obj(id,name,cls),obj(id,name,cls),obj(id,name,cls)] 记录为对象 5 v2 = models.Books.objects.values('id','name') 6 # QuerySet 7 # [{'id':1,'name':'C++'},{'id':2,'name':'English'}] 记录为字典 8 v3 = models.Books.objects.values_list('id','cls') 9 # QuerySet 10 # [(1,编程),(2,语言),(3,社会)]记录为集合 11 12 return render(req,'books.html',{'v1':v1,'v2':v2,'v3':v3})
template中books页面代码: (涉及模板语言)

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <ul> 9 <h1>图书列表(对象)</h1> 10 {% for row in v1 %} 11 <p>{{ row.id }}-{{ row.name }} - {{ row.cls }}</p> 12 {% endfor %} 13 14 </ul> 15 16 <ul> 17 <h1>图书列表(字典)</h1> 18 {% for row in v2 %} 19 <p>{{ row.id }}-{{ row.name }} </p> 20 {% endfor %} 21 22 </ul> 23 24 25 <ul> 26 <h1>图书列表(集合)</h1> 27 {% for row in v3 %} 28 <p>{{ row.0 }}-{{ row.1 }} </p> 29 {% endfor %} 30 31 </ul> 32 33 </body> 34 </html>
3、实现场景:
三、跨表数据的获取(一对多,多对多各三种方式)
-
一对多
1、在models下生成的一对多表的跨表数据有三种获取方式(在views中的操作):
方式一:
v1 = models.Publisher.objects.filter(nid__gt=0)
# 等同于v1 = models.Publisher.objects.all()
# 拿到的是QuerySet,内部是对象
# <QuerySet [<Publisher: Publisher object (1)>, <Publisher: Publisher object (2)>, <Publisher: Publisher object (3)>, <Publisher: Publisher object (4)>]>
方式二:
v2 = models.Publisher.objects.filter(nid__gt=0).values('nid','address','name','pub__name')
# 拿到的是QuerySet,内部是字典,跨表操作要用双下划线
# [{{'nid': 1, 'address': '北京', 'pub_id': 1, 'pub__name': 'C++', },{...},{...}]
方式三:
v3 = models.Publisher.objects.filter(nid__gt=0).values_list('nid','address','name','pub__name')
# 拿到的QuerySet,内部是元组
# [(1, '北京', '北京出版社', 'C++'),(),()]
2、示例代码
models中的代码:

1 class Books(models.Model): 2 name = models.CharField(max_length=32) 3 cls = models.CharField(max_length=32) 4 5 class Publisher(models.Model): 6 nid = models.AutoField(primary_key=True) 7 name = models.CharField(max_length=32) 8 address = models.CharField(max_length=32) 9 pub = models.ForeignKey(to='Books',to_field='id',on_delete=models.CASCADE)
注:生成两个表格,一个是图书数据库表,一个是出版社(书店)数据库表,外键为pub
views中的代码:

1 def PublisherInfo(req): 2 v1 = models.Publisher.objects.filter(nid__gt=0) 3 # 等同于v1 = models.Publisher.objects.all() 4 print(v1) 5 # 拿到的是QuerySet,内部是对象 6 # <QuerySet [<Publisher: Publisher object (1)>, <Publisher: Publisher object (2)>, <Publisher: Publisher object (3)>, <Publisher: Publisher object (4)>]> 7 print(v1[0].pub) # 跨表拿到第一对象的第一个对象 8 print(v1[0].pub.name) # 跨表拿到的第一个对象的第一个对象的名字 9 # print(v1[0].pub_id.name) 'int' object has no attribute 'name' 10 11 for row in v1: 12 print(row.nid,row.name,row.address,row.pub_id,row.pub) 13 14 # print(v1[0].name) 15 # print(v1[0].address) 16 # print(v1[0].nid) 17 # print(v1[0].pub) 18 # print(v1[0].pub_id) 19 # print(v1[0].pub.name) 20 21 22 v2 = models.Publisher.objects.filter(nid__gt=0).values('nid','address','name','pub__name') 23 # 拿到的是QuerySet,内部是字典,跨表操作要用双下划线 24 # [{{'nid': 1, 'address': '北京', 'pub_id': 1, 'pub__name': 'C++', },{...},{...}] 25 print(v2) 26 for row in v2: 27 print(row['nid'],row['address'],row['name'],row['pub__name']) 28 29 30 v3 = models.Publisher.objects.filter(nid__gt=0).values_list('nid','address','name','pub__name') 31 # 拿到的QuerySet,内部是元组 32 # [(1, '北京', '北京出版社', 'C++'),(),()] 33 print(v3) 34 for row in v3: 35 print(row[0],row[1],row[2],row[3]) 36 37 return render(req,'pub.html',{'v2':v2,'v1':v1,'v3':v3})
template中books页面代码: (涉及模板语言和HTML表格标签)

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 9 10 <h1>版社信息(集合)</h1> 11 <table border="1"> 12 13 <thead> 14 <tr> 15 <th> 编号</th> 16 <th>出版社</th> 17 <th>地址</th> 18 <th>书名</th> 19 </tr> 20 21 </thead> 22 23 <tbody> 24 {% for row in v1 %} 25 <tr> 26 <td>{{ row.nid }}</td> 27 <td>{{ row.name }}</td> 28 <td>{{ row.address }}</td> 29 <td>{{ row.pub.name }}</td> 30 </tr> 31 {% endfor %} 32 33 </tbody> 34 35 36 </table> 37 38 39 40 41 42 43 <h1>图书信息(字典)</h1> 44 <table border="1"> 45 46 <thead> 47 <tr> 48 <th>序号</th> 49 <th>书名</th> 50 <th>出版社</th> 51 </tr> 52 53 </thead> 54 55 </tbody> 56 {% for row in v2 %} 57 <tr> 58 <td>{{ forloop.revcounter }}</td> 59 {# <td>{{ forloop.counter0 }}</td>#} 60 {# <td>{{ forloop.revcounter }}</td>#} 61 <td>{{ row.pub__name }}</td> 62 <td>{{ row.name }}</td> 63 </tr> 64 {% endfor %} 65 66 </tbody> 67 68 </table> 69 70 71 72 <h1>汇总信息(集合)</h1> 73 <table border="1"> 74 75 <thead> 76 <tr> 77 <th>编号</th> 78 <th>地址</th> 79 <th>出版社</th> 80 <th>书名</th> 81 </tr> 82 83 </thead> 84 85 <tbody> 86 {% for row in v3 %} 87 <tr> 88 <td>{{ row.0 }}</td> 89 <td>{{ row.1 }}</td> 90 <td>{{ row.2 }}</td> 91 <td>{{ row.3 }}</td> 92 </tr> 93 {% endfor %} 94 95 </tbody> 96 97 </table> 98 99 100 101 102 </body> 103 </html>
3、实现场景:
· 多对多(系统自动生成的第三章对应表)
1、在models下生成的多对多表的跨表数据有三种获取方式(在views中的操作):
models下的表结构:
class Book(models.Model):
name = models.CharField(max_length=16)
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=16)
m = models.ManyToManyField('Book')
def __str__(self):
return self.name
方式一:
author_list = models.Author.objects.all()
# 拿到的是QuerySet,里面是对象
for author in author_list:
print(author.name,author.m.all())
方式二:
author_list = models.Author.objects.values('id','name','m','m__name') # 注意最后一个__
# 拿到的是QuerySet 内部是字典,跨表操作用__
for item in author_list:
print(item['id'],item['name'],'书籍ID:',item['m'],item['m__name'])
方式三:
author_list = models.Author.objects.values_list('id','name','m','m__name')
# 拿到的是QuerySet,内部是元组
for item in author_list:
print(item[0],item[1],
item[2],item[3])
2、跨表查询
1)正向查询
obj = models.Author.objects.get(id=1)
# 拿到Author中第一个作者
obj.m.all()
# 通过m 取到第一个作者在第三张表中的所有作品
for i in obj.m.all():
print(i.name)
2)反向查询
obj = models.Book.objects.get(id=1)
# 拿到第一本书
obj.author_set.all() # 注意用author__set
# 第一本书的关联作者
3、添加数据
1)正向添加
obj = models.Author.objects.get(id=1)
obj.m.add(5)
obj.m.add(*[4,5])
obj.m.clear() # 清空当前作者的所有作品
obj.m.set([1,2,3]) # 清空当前其他对应,传入这些,类似更新
2)反向添加
obj = models.Book.objects.get(id=1)
obj.author_set.add(4)
obj.author_set.add(1,2,3) # 其他同上
四、利用模态对话框实现外部对表的操作(练习模态对话框和js、jQuery功能)
1、利用二中生成的Publisher和Books表,用模态对话框进行添加数据操作(初级操作)
1)templa中的html页面:

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 .hide{ 8 display: none; 9 } 10 .shade{ 11 position: fixed; 12 top: 0; 13 right: 0; 14 left: 0; 15 bottom: 0; 16 background-color: black; 17 opacity: 0.6; 18 z-index: 100; 19 } 20 21 .add_modal{ 22 position: fixed; 23 height: 300px; 24 width: 400px; 25 top: 100px; 26 left: 50%; 27 z-index: 101; 28 border: 3px solid black; 29 background-color: white; 30 margin-left: -200px; 31 } 32 .ppp{ 33 position: fixed; 34 top: 130px; 35 left: 45%; 36 z-index: 102; 37 } 38 39 </style> 40 </head> 41 <body> 42 43 44 <h1>版社信息(集合)</h1> 45 <div> 46 <input id="add_book" type="button" value="添加"> 47 </div> 48 <table border="1"> 49 50 <thead> 51 <tr> 52 <th> 编号</th> 53 <th>出版社</th> 54 <th>地址</th> 55 <th>书名</th> 56 </tr> 57 58 </thead> 59 60 <tbody> 61 {% for row in v1 %} 62 <tr> 63 <td>{{ row.nid }}</td> 64 <td>{{ row.name }}</td> 65 <td>{{ row.address }}</td> 66 <td>{{ row.pub.name }}</td> 67 </tr> 68 {% endfor %} 69 70 </tbody> 71 72 73 </table> 74 75 76 <h1>图书信息(字典)</h1> 77 <table border="1"> 78 79 <thead> 80 <tr> 81 <th>序号</th> 82 <th>书名</th> 83 <th>出版社</th> 84 </tr> 85 86 </thead> 87 88 </tbody> 89 {% for row in v2 %} 90 <tr> 91 <td>{{ forloop.revcounter }}</td> 92 {# <td>{{ forloop.counter0 }}</td>#} 93 {# <td>{{ forloop.revcounter }}</td>#} 94 <td>{{ row.pub__name }}</td> 95 <td>{{ row.name }}</td> 96 </tr> 97 {% endfor %} 98 99 </tbody> 100 101 </table> 102 103 104 <h1>汇总信息(集合)</h1> 105 <table border="1"> 106 107 <thead> 108 <tr> 109 <th>编号</th> 110 <th>地址</th> 111 <th>出版社</th> 112 <th>书名</th> 113 </tr> 114 115 </thead> 116 117 <tbody> 118 {% for row in v3 %} 119 <tr> 120 <td>{{ row.0 }}</td> 121 <td>{{ row.1 }}</td> 122 <td>{{ row.2 }}</td> 123 <td>{{ row.3 }}</td> 124 </tr> 125 {% endfor %} 126 127 </tbody> 128 129 </table> 130 131 132 # 主要是以下代码和title中的style设计 133 134 <div class="shade hide"></div> 135 <div class="add_modal hide"> 136 <form method="POST" action="/publisher/info/"> 137 138 <div class="ppp"> 139 <div class="group"> 140 <input type="text" placeholder="出版社" name="name"> 141 </div> 142 143 <div class="group"> 144 <input type="text" placeholder="地址" name="address"> 145 </div> 146 147 <div> 148 <select name="b_id"> 149 {% for i in b_list %} 150 <option value="{{ i.id }}">{{ i.name }}</option> 151 {% endfor %} 152 153 154 </select> 155 </div> 156 157 <input type="submit" value="提交"> 158 <input id="cancel" type="button" value="取消"> 159 160 </div> 161 162 </form> 163 164 165 </div> 166 167 168 169 170 171 <script src="/static/jquery-3.3.1.js"></script> 172 <script> 173 $(function () { 174 $('#add_book').click(function () { 175 $('.shade,.add_modal').removeClass('hide') 176 }) 177 178 $('#cancel').click(function () { 179 $('.shade,.add_modal').addClass('hide') 180 181 }) 182 183 184 }) 185 </script> 186 </body> 187 </html>
2)views中的数据获取及操作:

1 def PublisherInfo(req): 2 if req.method == 'GET': 3 v1 = models.Publisher.objects.filter(nid__gt=0) 4 v2 = models.Publisher.objects.filter(nid__gt=0).values('nid','address','name','pub__name') 5 v3 = models.Publisher.objects.filter(nid__gt=0).values_list('nid','address','name','pub__name') 6 b_list = models.Books.objects.all() 7 8 return render(req,'pub.html',{'v2':v2,'v1':v1,'v3':v3,'b_list':b_list}) 9 elif req.method == "POST": 10 n = req.POST.get('name') 11 a = req.POST.get('address') 12 b = req.POST.get('b_id') 13 print(n,a,b) 14 # models.Publisher.objects.create(name=n,address=a, 15 # pub = models.Books.objects.filter(id=b) 16 # ) 17 # 外键pub应该是对象,Books中id为b的对象,以上麻烦,更改为下面这句 18 models.Publisher.objects.create(name=n,address=a,pub_id=b) 19 20 return redirect('/publisher/info') # 这里要用redirect
3)实现
2、对表实现前端的操作(中级操作)
1)models下生成Class数据库表

1 from django.db import models 2 3 # Create your models here. 4 5 class Classes(models.Model): 6 nid = models.IntegerField(primary_key=True) 7 cls = models.CharField(max_length=16) 8 address = models.CharField(max_length=16)
2)url中的路径

1 from django.urls import path 2 from app01 import views 3 4 urlpatterns = [ 5 path('admin/', admin.site.urls), 6 7 8 path('class/info/', views.ClassInfo), 9 path('class/edit/', views.ClassEdit), 10 path('class/delete/', views.ClassDelete), 11 12 ]
3)views中的函数实现

1 from django.shortcuts import render,redirect,HttpResponse 2 from app01 import models 3 4 # Create your views here. 5 6 def ClassInfo(request): 7 if request.method == 'POST': 8 9 ''' 10 form 表单提交方式 11 c = request.POST.get('cls') 12 a = request.POST.get('addr') 13 if c and a: 14 models.Classes.objects.create(cls=c,address=a) 15 class_list = models.Classes.objects.all() 16 return render(request, 'class.html', {'classlist': class_list}) 17 ''' 18 import json 19 c = request.POST.get('cls') 20 a = request.POST.get('addr') 21 response_dict={'status':True,'error':None,'data':None} 22 if c and a: 23 models.Classes.objects.create(cls=c,address=a) 24 25 else: 26 response_dict['status'] = False 27 response_dict['error'] = '不能为空' 28 return HttpResponse(json.dumps(response_dict)) 29 else: 30 class_list = models.Classes.objects.all() 31 return render(request, 'class.html', {'classlist': class_list}) 32 33 34 def ClassEdit(request): 35 if request.method == "POST": 36 id = request.POST.get('edit_id',None) 37 e = request.POST.get('edit_name',None) 38 a = request.POST.get('edit_addr',None) 39 models.Classes.objects.filter(nid=id).update(cls=e,address=a) 40 class_list = models.Classes.objects.all() 41 return render(request, 'class.html', {'classlist': class_list}) 42 else: 43 class_list = models.Classes.objects.all() 44 return render(request,'class.html',{'classlist':class_list}) 45 46 47 def ClassDelete(request): 48 if request.method == 'POST': 49 d = request.POST.get('edit_delete_id') 50 51 if d: 52 print(d) 53 models.Classes.objects.filter(nid=d).delete() 54 return redirect('/class/info') 55 else: 56 return redirect('/class/info') 57 else: 58 return redirect('/class/info')
4)template中的HTML页面(重点练习标签函数和取值)
要引入jQuery,只有一个class.html页面

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 .hide{ 8 display: none; 9 } 10 11 .shade{ 12 position: fixed; 13 background-color: black; 14 top: 0; 15 left: 0; 16 right: 0; 17 bottom: 0; 18 opacity: 0.6; 19 z-index: 100; 20 } 21 .add_modal{ 22 position: fixed; 23 background-color: white; 24 height: 300px; 25 width: 400px; 26 top: 100px; 27 left: 50%; 28 border: 3px solid black; 29 margin-left: -200px; 30 z-index: 101; 31 32 33 } 34 35 .edit_shade{ 36 position: fixed; 37 background-color: black; 38 top: 0; 39 left: 0; 40 right: 0; 41 bottom: 0; 42 opacity: 0.6; 43 z-index: 100; 44 45 } 46 47 .edit_add_modal{ 48 position: fixed; 49 background-color: white; 50 height: 300px; 51 width: 400px; 52 top: 100px; 53 left: 50%; 54 border: 3px solid black; 55 margin-left: -200px; 56 z-index: 101; 57 } 58 59 .edit-delete{ 60 position: fixed; 61 background-color: black; 62 opacity: 0.6; 63 top: 0; 64 right: 0; 65 left: 0; 66 bottom: 0; 67 z-index: 100; 68 } 69 70 .delete-add-modal{ 71 position: fixed; 72 background-color: white; 73 top: 100px; 74 height: 200px; 75 width: 300px; 76 right: 50%; 77 margin-right: -150px; 78 z-index: 101; 79 80 } 81 82 83 84 85 86 </style> 87 </head> 88 89 <body> 90 91 <table border="1"> 92 <input type="button" value="添加" id="add_class"> 93 <thead> 94 <tr> 95 <td>序号</td> 96 <td>班级编号</td> 97 <td>班级</td> 98 <td>班级地址</td> 99 <td>操作</td> 100 </tr> 101 102 </thead> 103 <tbody> 104 {% for cls in classlist %} 105 <tr> 106 <td>{{ forloop.counter }}</td> 107 <td>{{ cls.nid }}</td> 108 <td>{{ cls.cls }}</td> 109 <td>{{ cls.address }}</td> 110 <td> 111 <button class="td_edit">编辑</button>|<button class="td-delete">删除</button> 112 113 </td> 114 </tr> 115 116 {% endfor %} 117 </tbody> 118 </table> 119 120 <div class="shade hide"> </div> 121 <div class="add_modal hide"> 122 <form action="/class/info/" method="POST"> 123 <input type="text" placeholder="班级" name="cls"> 124 <input type="text" placeholder="班级地址" name="addr"> 125 <input type="submit" value="添加"> 126 127 </form> 128 <input type="submit" id="cancel" value="取消"> 129 </div> 130 131 <div class="shade hide"> </div> 132 <div class="add_modal hide"> 133 <form action="/class/info/" method="POST"> 134 <input type="text" id="input1" placeholder="班级" name="cls"> 135 <input type="text" id="input2" placeholder="班级地址" name="addr"> 136 <input type="submit" value="submit添加"> 137 <input type="submit" id="cancel" value="取消"> 138 <input type="button" id="ajax_submit" value="Ajax提交"> 139 </form> 140 141 </div> 142 143 144 145 146 <div class="edit_shade hide"></div> 147 <div class="edit_add_modal hide"> 148 <form action="/class/edit/" method="POST"> 149 <input type="text" name="edit_id" hidden> 150 <input type="text" name="edit_name"> 151 <input type="text" name="edit_addr"> 152 <input type="submit" value="更新"> 153 <input type="submit" id="edit_cancle" value="取消"> 154 </form> 155 156 </div> 157 158 159 160 <div class="edit-delete hide"></div> 161 <div class="delete-add-modal hide"> 162 <form action="/class/delete/" method="POST"> 163 <input type="text" name="edit_delete_id" hidden> 164 <input type="submit" value="确定"> 165 <input type="submit" id="delete_cancel" value="取消"> 166 </form> 167 </div> 168 169 170 171 172 173 <script src="/static/jquery-3.3.1.js"></script> 174 <script> 175 176 $(function () { 177 178 $('#add_class').click(function () { 179 $('.shade,.add_modal').removeClass('hide') 180 }) 181 182 $('#cancel').click(function () { 183 $('.shade,.add_modal').addClass('hide') 184 }) 185 186 187 188 189 190 $('.td_edit').on('click',function () { 191 $('.edit_shade,.edit_add_modal').removeClass('hide') 192 var tds = $(this).parent().prevAll() 193 $('.edit_add_modal input[name="edit_name"]').val(tds[1].innerText); 194 $('.edit_add_modal input[name="edit_addr"]').val(tds[0].innerText); 195 $('.edit_add_modal input[name="edit_id"]').val(tds[2].innerText); 196 }) 197 198 199 $('#edit_cancle').on('click',function () { 200 $('.edit_shade,.edit_add_modal').addClass('hide') 201 }) 202 203 204 205 $('#ajax_submit').on('click',function () { 206 207 var value1 = $('#input1').val(); 208 var value2 = $('#input2').val(); 209 console.log(value1,value2) 210 $.ajax( 211 { 212 url:'/class/info/', 213 type:'POST', 214 dataType:'JSON', 215 data:{cls:value1,addr:value2}, 216 success:function (data) { 217 // data = JSON.parse(data) 和上面dataType二选一 218 if(!data.status){ 219 alert(data.error) 220 }else{ 221 location.reload();// 实现页面刷新 222 } 223 } 224 } 225 ) 226 227 228 }) 229 230 231 232 233 $('.td-delete').click(function () { 234 $('.edit-delete, .delete-add-modal').removeClass('hide') 235 var td_deletes = $(this).parent().prevAll() 236 $('.delete-add-modal input[name="edit_delete_id"]').val(td_deletes[2].innerText) 237 238 239 }) 240 241 $('#delete_cancel').click(function () { 242 $('.edit-delete, .delete-add-modal').addClass('hide') 243 $('.delete-add-modal input[name="edit_delete_id"]').val(0) 244 }) 245 246 }) 247 248 249 </script> 250 </body> 251 </html>
5)实现
五、完整训练项目
-
models

1 from django.db import models 2 3 # Create your models here. 4 5 class Classes(models.Model): 6 nid = models.IntegerField(primary_key=True) 7 cls = models.CharField(max_length=16) 8 address = models.CharField(max_length=16) 9 10 class Students(models.Model): 11 name = models.CharField(max_length=16) 12 cls = models.ForeignKey(to='Classes',to_field='nid',on_delete=models.CASCADE) 13 14 class Teachers(models.Model): 15 name = models.CharField(max_length=16) 16 program = models.CharField(max_length=16) 17 phone_number = models.IntegerField() 18 cls = models.ManyToManyField('Classes')
-
urls

1 from django.contrib import admin 2 from django.urls import path,re_path 3 from app01 import views 4 5 urlpatterns = [ 6 path('admin/', admin.site.urls), 7 path('index/', views.index), 8 9 10 11 path('class/info/', views.ClassInfo), 12 path('add/class/', views.AddClass), 13 path('class/edit/', views.ClassEdit), 14 path('class/delete/', views.ClassDelete), 15 16 path('student/info/', views.StudentInfo), 17 18 19 path('teacher/info/', views.TeacherInfo), 20 21 path('add/teacher/', views.AddTeacher), 22 re_path('edit/teacher-(\d+)/', views.EditTeacher), 23 # 参考:http://www.liujiangblog.com/course/django/182 24 # 参考:https://blog.csdn.net/u010937045/article/details/81541376
-
views

1 from django.shortcuts import render,redirect,HttpResponse 2 from app01 import models 3 4 # Create your views here. 5 6 7 def index(request): 8 return render(request,'index.html') 9 10 11 def ClassInfo(request): 12 if request.method == 'POST': 13 14 ''' 15 form 表单提交方式 16 c = request.POST.get('cls') 17 a = request.POST.get('addr') 18 if c and a: 19 models.Classes.objects.create(cls=c,address=a) 20 class_list = models.Classes.objects.all() 21 return render(request, 'class.html', {'classlist': class_list}) 22 ''' 23 import json 24 c = request.POST.get('cls') 25 a = request.POST.get('addr') 26 response_dict={'status':True,'error':None,'data':None} 27 if c and a: 28 models.Classes.objects.create(cls=c,address=a) 29 30 else: 31 response_dict['status'] = False 32 response_dict['error'] = '不能为空' 33 return HttpResponse(json.dumps(response_dict)) 34 else: 35 36 # class_list = models.Classes.objects.all() 37 38 39 ''' 40 # 自动分页(在前端显示所有的页) 41 # 引入 42 # for i in range(100): 43 # models.Classes.objects.create(cls='全栈班'+str(i),address=str(i)+'楼') 44 cuttent_page = request.GET.get('p',1) 45 cuttent_page = int(cuttent_page) 46 print(cuttent_page) 47 48 # 一页展示10个 49 # 1,0—10 50 # 2,11—20 51 # 3,21—30 52 start = (cuttent_page-1)*10 53 end = cuttent_page*10 54 55 56 # 对下面的pager字符串的处理 57 total_count = models.Classes.objects.all().count() 58 # 每页显示10条,用总数除以10得出页数,余数不为0加1是总页数 59 v,a = divmod(total_count,10) 60 if a != 0: 61 v +=1 62 pager_list = [] 63 64 pager_list.append('<a href="/class/info?p=%s">上一页</a>'%(cuttent_page-1)) 65 for i in range(1,v+1): 66 if i == cuttent_page: # 给当前页加样式 67 pager_list.append('<a class="active" href="/class/info?p=%s">%s</a>' % (i, i)) 68 else: 69 pager_list.append('<a href="/class/info?p=%s">%s</a>'%(i,i)) 70 pager_list.append('<a href="/class/info?p=%s">下一页</a>'%(cuttent_page+1)) 71 72 pager = "".join(pager_list) 73 74 from django.utils.safestring import mark_safe 75 76 77 ''' 78 pager=""" 79 <a href="/class/info?p=1">1</a> 80 <a href="/class/info?p=2">2</a> 81 <a href="/class/info?p=3">3</a> 82 <a href="/class/info?p=4">4</a> 83 84 """ 85 86 ''' 87 # 两种方式,一种是传入时如下用mark_safe(),一种是在前端 {{ str_pager | safe}} 88 class_list = models.Classes.objects.all()[start:end] 89 ''' 90 91 # 自动分页(在前端显示当前页前五个和后五个) 92 # 引入 93 # for i in range(100): 94 # models.Classes.objects.create(cls='全栈班'+str(i),address=str(i)+'楼') 95 cuttent_page = request.GET.get('p', 1) 96 cuttent_page = int(cuttent_page) 97 print(cuttent_page) 98 99 # 一页展示10个 100 # 1,0—10 101 # 2,11—20 102 # 3,21—30 103 ''' 104 封装到类中的db_start和db_end中 105 start = (cuttent_page - 1) * 10 106 end = cuttent_page * 10 107 ''' 108 109 110 # 对下面的pager字符串的处理 111 total_count = models.Classes.objects.all().count() 112 # 每页显示10条,用总数除以10得出页数,余数不为0加1是总页数 113 from utils.page import PgerHelper 114 obj = PgerHelper(total_count,cuttent_page,'/class/info') 115 pager = obj.page_str() 116 117 # 以下封装到类中 118 ''' 119 v, a = divmod(total_count, 10) 120 if a != 0: 121 v += 1 122 pager_list = [] 123 if cuttent_page == 1: 124 pager_list.append('<a href="#">上一页</a>') 125 else: 126 pager_list.append('<a href="/class/info?p=%s">上一页</a>' % (cuttent_page - 1)) 127 128 # 当前页为6,显示1-12 129 # 当前页为7,显示2-13 130 131 # page_range_start = cuttent_page - 5 132 # page_range_end = cuttent_page + 6 133 # 以上两句到末端无法处理,要改为以下代码 134 135 if v <= 11: 136 page_range_start = 1 137 page_range_end = v 138 else: 139 if cuttent_page < 6: 140 page_range_start = 1 141 page_range_end = 12 142 else: 143 page_range_start = cuttent_page - 5 144 page_range_end = cuttent_page + 6 145 if page_range_end > v : 146 page_range_end = v + 1 147 page_range_start = v - 10 148 149 for i in range(page_range_start, page_range_end): 150 if i == cuttent_page: # 给当前页加样式 151 pager_list.append('<a class="active" href="/class/info?p=%s">%s</a>' % (i, i)) 152 else: 153 pager_list.append('<a href="/class/info?p=%s">%s</a>' % (i, i)) 154 155 if cuttent_page == v: 156 pager_list.append('<a href="#">下一页</a>') 157 else: 158 pager_list.append('<a href="/class/info?p=%s">下一页</a>' % (cuttent_page + 1)) 159 160 pager = "".join(pager_list) 161 ''' 162 163 164 165 from django.utils.safestring import mark_safe 166 167 ''' 168 pager=""" 169 <a href="/class/info?p=1">1</a> 170 <a href="/class/info?p=2">2</a> 171 <a href="/class/info?p=3">3</a> 172 <a href="/class/info?p=4">4</a> 173 174 """ 175 176 ''' 177 # 两种方式,一种是传入时如下用mark_safe(),一种是在前端 {{ str_pager | safe}} 178 class_list = models.Classes.objects.all()[obj.db_start:obj.db_end] 179 180 181 182 183 return render(request, 'class.html', {'classlist': class_list,'str_pager':mark_safe(pager)}) 184 185 186 def ClassEdit(request): 187 if request.method == "POST": 188 id = request.POST.get('edit_id',None) 189 e = request.POST.get('edit_name',None) 190 a = request.POST.get('edit_addr',None) 191 models.Classes.objects.filter(nid=id).update(cls=e,address=a) 192 class_list = models.Classes.objects.all() 193 return render(request, 'class.html', {'classlist': class_list}) 194 else: 195 class_list = models.Classes.objects.all() 196 197 198 199 return render(request,'class.html',{'classlist':class_list}) 200 201 202 def AddClass(request): 203 msg = '' 204 if request.method == 'GET': 205 return render(request,'addclass.html',{'msg':msg}) 206 elif request.method == "POST": 207 c = request.POST.get('cls') 208 a = request.POST.get('addr') 209 if c and a: 210 models.Classes.objects.create(cls=c,address=a) 211 return render(request,'addclass.html',{'msg':msg}) 212 else: 213 msg = '班级名称或地址不能为空' 214 return render(request,'addclass.html',{'msg':msg}) 215 216 217 218 def ClassDelete(request): 219 if request.method == 'POST': 220 d = request.POST.get('edit_delete_id') 221 222 if d: 223 print(d) 224 models.Classes.objects.filter(nid=d).delete() 225 return redirect('/class/info') 226 else: 227 return redirect('/class/info') 228 else: 229 return redirect('/class/info') 230 231 232 def StudentInfo(request): 233 return render(request,'student.html') 234 235 236 def TeacherInfo(request): 237 if request.method == 'POST': 238 v1 = request.POST.get('v1') 239 v2 = request.POST.get('v2') 240 obj = models.Teachers.objects.get(id=v1) 241 obj.cls.remove(v2) 242 return HttpResponse('删除成功!') 243 else: 244 # teacher_list = models.Teachers.objects.all() 245 teacher_list = models.Teachers.objects.values('id','name','cls__nid','cls__cls') 246 # teacher_list = models.Teachers.objects.values('id','name','cls__nid','cls__cls')[0:5] 247 # 上面的切片显示的是values里面的前五个,而非Teachers里面的前五个 248 # teacher_list = models.Teachers.objects.filter(id__in=models.Teachers.objects.all()[0:5]).values('id','name','cls__nid','cls__cls') 249 # 此时的切片是显示的五个老师 250 result = {} 251 for obj in teacher_list: 252 # print(obj['id'],obj['name'],obj['cls__nid'],obj['cls__cls']) 253 254 if obj['id'] in result: 255 if obj['cls__nid']: 256 result[obj['id']]['cls_list'].append({'nid':obj['cls__nid'], 'cls':obj['cls__cls']}) 257 else: 258 if obj['cls__nid']: 259 temp = [ 260 {'nid':obj['cls__nid'],'cls':obj['cls__cls']} 261 ] 262 else: 263 temp = [] 264 result[obj['id']] = { 265 'nid':obj['id'], 266 'name':obj['name'], 267 'cls_list':temp 268 } 269 270 ''' 271 上面for循环变为下面的数据结构 272 result = { 273 1:{ 274 'nid':1, 275 'name':'张三', 276 'cls_list':[ 277 {'nid':1, 'cls':'一年级'} 278 ] 279 }, 280 281 3: { 282 'nid': 3, 283 'name': '李文', 284 'cls_list': [ 285 {'nid':1,'cls':'一年级'} 286 {'nid':5,'cls':'五年级'} 287 ] 288 } 289 290 } 291 ''' 292 293 294 295 296 297 # 前端插曲(在前端取字典) 298 299 li = ['alex','123'] 300 print(li[0]) 301 print(li[1]) 302 for i in li: 303 print(i) 304 305 dict_list ={ 306 'k1':'alex', 307 'k2':'123' 308 } 309 print(dict_list['k1']) 310 print(dict_list['k2']) 311 for i in dict_list: 312 print(i) 313 for i in dict_list.keys(): 314 print(i) 315 for i in dict_list.values(): 316 print(i) 317 for i,v in dict_list.items(): 318 print(i,v) 319 320 tuple = ('alex','123') 321 print(tuple[0]) 322 print(tuple[1]) 323 for i in tuple: 324 print(i) 325 326 return render(request,'teacher.html', 327 {'dict_list':dict_list, 328 'teacher_list':result, 329 'li':li, 330 'tuple':tuple}) 331 332 333 def AddTeacher(request): 334 if request.method == 'GET': 335 cls_list = models.Classes.objects.all() 336 return render(request,'addteacher.html',{'cls_list':cls_list}) 337 elif request.method == "POST": 338 name = request.POST.get('name') 339 program = request.POST.get('program') 340 phone = request.POST.get('phone') 341 cls = request.POST.getlist('cls') 342 # print(name,cls) 343 # 接下来要创建老师对象并在第三张表中插入数据了,此时简洁代码如下 344 obj = models.Teachers.objects.create(name=name, 345 program=program, 346 phone_number=phone) # 不仅创建了这个老师,而且拿到这个老师对象进行操作 347 obj.cls.add(*cls) 348 return redirect('/teacher/info/') 349 350 351 def EditTeacher(request,nid): 352 if request.method == 'GET': 353 obj = models.Teachers.objects.get(id=nid) 354 # obj_cls_list = obj.cls.all() 便于判断哪些班级在这个老师下,所以变为元组 355 obj_cls_list = obj.cls.all().values_list('nid','cls') # 取到本老师下的所带班级nid和cls 356 # 引入zip 357 # a = [(1,'root1'),(2,'root2'),(3,'root3')] 358 # list(zip(*a)) 后a == [(1,2,3),('root1','root2','root3')] 359 360 # id_list = list(zip(*obj_cls_list))[0] 这里后期修改为以下,判断为空或有数据时,此时值为bool值,用print验证 361 id_list = list(zip(*obj_cls_list))[0] if obj_cls_list else [] 362 # 如果obj_cls_list为真,用前面的,如果obj_cls_list为假的话用后面这个(空列表) 363 print(id_list) 364 cls_list = models.Classes.objects.all() # 取到所有的班级 365 cls_exclude_list = models.Classes.objects.exclude(nid__in=id_list) 366 # 取到不包括已经管理班级,即未带班级 367 368 return render(request,'edit-teacher.html',{'obj':obj,'cls_list':cls_list, 369 'id_list':id_list, 370 'obj_cls_list':obj_cls_list, 371 'cls_exclude_list':cls_exclude_list}) 372 elif request.method == 'POST': 373 n = request.POST.get('name') 374 p = request.POST.get('program') 375 ph = request.POST.get('phone') 376 c_li = request.POST.getlist('teacher_cls') 377 obj = models.Teachers.objects.get(id=nid) 378 obj.name = n 379 obj.program = p 380 obj.phone_number = ph 381 obj.save() 382 obj.cls.set(c_li) 383 return redirect('/teacher/info/')
-
template
layout.html

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 body{ 8 margin: 0; 9 } 10 .menu .item{ 11 display: block; 12 padding: 5px 10px; 13 {#上下等于5,左右等于10#} 14 border-bottom: 1px solid #dddddd; 15 } 16 .menu .item:hover{ 17 background-color: black; 18 color: white; 19 } 20 .menu .item.active{ 21 background-color: black; 22 color: white; 23 } 24 25 .hide{ 26 display: none; 27 } 28 29 .shade{ 30 position: fixed; 31 background-color: black; 32 top: 0; 33 left: 0; 34 right: 0; 35 bottom: 0; 36 opacity: 0.6; 37 z-index: 100; 38 } 39 .add_modal{ 40 position: fixed; 41 background-color: white; 42 height: 300px; 43 width: 400px; 44 top: 100px; 45 left: 50%; 46 border: 3px solid black; 47 margin-left: -200px; 48 z-index: 101; 49 50 51 } 52 53 .edit_shade{ 54 position: fixed; 55 background-color: black; 56 top: 0; 57 left: 0; 58 right: 0; 59 bottom: 0; 60 opacity: 0.6; 61 z-index: 100; 62 63 } 64 65 .edit_add_modal{ 66 position: fixed; 67 background-color: white; 68 height: 300px; 69 width: 400px; 70 top: 100px; 71 left: 50%; 72 border: 3px solid black; 73 margin-left: -200px; 74 z-index: 101; 75 } 76 77 .edit-delete{ 78 position: fixed; 79 background-color: black; 80 opacity: 0.6; 81 top: 0; 82 right: 0; 83 left: 0; 84 bottom: 0; 85 z-index: 100; 86 } 87 88 .delete-add-modal{ 89 position: fixed; 90 background-color: white; 91 top: 100px; 92 height: 200px; 93 width: 300px; 94 right: 50%; 95 margin-right: -150px; 96 z-index: 101; 97 98 } 99 .pagination a{ 100 display: inline-block; 101 padding: 5px; 102 } 103 .pagination a.active{ 104 background-color: black; 105 color: white; 106 } 107 108 109 </style> 110 {% block css %}{% endblock %} 111 </head> 112 <body> 113 <div style="height: 48px;background-color: black;color: white"> 114 <div style="float: right">欢迎|<a>注销</a></div> 115 </div> 116 117 <div> 118 <div class="menu" style="position: absolute;width:200px;top: 50px;left:0;bottom: 0;background-color: blanchedalmond"> 119 <a id="menu_class" class="item" href="/class/info/">班级管理</a> 120 <a id="menu_student" class="item" href="/student/info/">学生管理</a> 121 <a id="menu_teacher" class="item" href="/teacher/info/">老师管理</a> 122 </div> 123 <div style="position: absolute;left:200px;top: 50px;right:0;bottom: 0;overflow: auto;background-color: palevioletred"> 124 {% block content %}{% endblock %} 125 </div> 126 </div> 127 <script src="/static/jquery-3.3.1.js"></script> 128 {% block js %}{% endblock %} 129 </body> 130 </html>
addclass.html

1 {% extends 'layout.html' %} 2 3 {% block css %} 4 5 {% endblock %} 6 7 8 {% block content %} 9 <h1>添加班级</h1> 10 <form action="/add/class/" method="POST"> 11 <input type="text" placeholder="班级名称" name="cls"> 12 <input type="text" placeholder="班级楼层" name="addr"> 13 <input type="submit" value="添加">{{ msg }} 14 15 </form> 16 {% endblock %} 17 18 19 {% block js %} 20 <script> 21 22 </script> 23 {% endblock %}
addteacher.html

1 {% extends 'layout.html' %} 2 3 {% block css %} 4 5 {% endblock %} 6 7 8 {% block content %} 9 <h1>添加老师</h1> 10 <form action="/add/teacher/" method="POST"> 11 <p> 12 老师姓名:<input type="text" name="name"> 13 </p> 14 <p> 15 所教学科:<input type="text" name="program"> 16 </p> 17 <p> 18 联系电话:<input type="text" name="phone"> 19 </p> 20 <p> 21 所带班级: 22 <select name="cls" multiple> 23 {% for cls in cls_list %} 24 <option value="{{ cls.nid }}">{{ cls.cls }}</option> 25 {% endfor %} 26 27 </select> 28 </p> 29 <p> 30 <input type="submit" value="提交"> 31 </p> 32 </form> 33 34 {% endblock %} 35 36 {% block js %} 37 <script> 38 $(function () { 39 $('#menu_teacher').addClass('active') 40 }) 41 42 43 </script> 44 {% endblock %}
class.html

1 {% extends 'layout.html' %} 2 3 {% block css %} 4 5 {% endblock %} 6 7 8 {% block content %} 9 <h1>班级列表</h1> 10 <table border="1"> 11 <input type="button" value="模态对话框类型添加" id="add_class"> 12 <a href="/add/class/">分页类型添加</a> 13 <thead> 14 <tr> 15 <td>序号</td> 16 <td>班级编号</td> 17 <td>班级</td> 18 <td>班级地址</td> 19 <td>操作</td> 20 </tr> 21 22 </thead> 23 <tbody> 24 {% for cls in classlist %} 25 <tr> 26 <td>{{ forloop.counter }}</td> 27 <td>{{ cls.nid }}</td> 28 <td>{{ cls.cls }}</td> 29 <td>{{ cls.address }}</td> 30 <td> 31 <button class="td_edit">编辑</button>|<button class="td-delete">删除</button> 32 33 </td> 34 </tr> 35 36 {% endfor %} 37 </tbody> 38 </table> 39 40 <div class="pagination"> 41 {{ str_pager }} 42 </div> 43 44 <div class="shade hide"> </div> 45 <div class="add_modal hide"> 46 <form action="/class/info/" method="POST"> 47 <input type="text" placeholder="班级" name="cls"> 48 <input type="text" placeholder="班级地址" name="addr"> 49 <input type="submit" value="添加"> 50 51 </form> 52 <input type="submit" id="cancel" value="取消"> 53 </div> 54 55 <div class="shade hide"> </div> 56 <div class="add_modal hide"> 57 <form action="/class/info/" method="POST"> 58 <input type="text" id="input1" placeholder="班级" name="cls"> 59 <input type="text" id="input2" placeholder="班级地址" name="addr"> 60 <input type="submit" value="submit添加"> 61 <input type="submit" id="cancel" value="取消"> 62 <input type="button" id="ajax_submit" value="Ajax提交"> 63 </form> 64 65 </div> 66 67 68 69 70 <div class="edit_shade hide"></div> 71 <div class="edit_add_modal hide"> 72 <form action="/class/edit/" method="POST"> 73 <input type="text" name="edit_id" hidden> 74 <input type="text" name="edit_name"> 75 <input type="text" name="edit_addr"> 76 <input type="submit" value="更新"> 77 <input type="submit" id="edit_cancle" value="取消"> 78 </form> 79 80 </div> 81 82 83 84 <div class="edit-delete hide"></div> 85 <div class="delete-add-modal hide"> 86 <form action="/class/delete/" method="POST"> 87 <input type="text" name="edit_delete_id" hidden> 88 <input type="submit" value="确定"> 89 <input type="submit" id="delete_cancel" value="取消"> 90 </form> 91 </div> 92 93 94 95 96 97 98 99 100 101 {% endblock %} 102 103 {% block js %} 104 <script> 105 $(function () { 106 $('#menu_class').addClass('active') 107 }) 108 </script> 109 110 <script> 111 112 $(function () { 113 114 $('#add_class').click(function () { 115 $('.shade,.add_modal').removeClass('hide') 116 }) 117 118 $('#cancel').click(function () { 119 $('.shade,.add_modal').addClass('hide') 120 }) 121 122 123 124 125 126 $('.td_edit').on('click',function () { 127 $('.edit_shade,.edit_add_modal').removeClass('hide') 128 var tds = $(this).parent().prevAll() 129 $('.edit_add_modal input[name="edit_name"]').val(tds[1].innerText); 130 $('.edit_add_modal input[name="edit_addr"]').val(tds[0].innerText); 131 $('.edit_add_modal input[name="edit_id"]').val(tds[2].innerText); 132 }) 133 134 135 $('#edit_cancle').on('click',function () { 136 $('.edit_shade,.edit_add_modal').addClass('hide') 137 }) 138 139 140 141 $('#ajax_submit').on('click',function () { 142 143 var value1 = $('#input1').val(); 144 var value2 = $('#input2').val(); 145 console.log(value1,value2) 146 $.ajax( 147 { 148 url:'/class/info/', 149 type:'POST', 150 dataType:'JSON', 151 data:{cls:value1,addr:value2}, 152 success:function (data) { 153 // data = JSON.parse(data) 和上面dataType二选一 154 if(!data.status){ 155 alert(data.error) 156 }else{ 157 location.reload();// 实现页面刷新 158 } 159 } 160 } 161 ) 162 163 164 }) 165 166 167 168 169 $('.td-delete').click(function () { 170 $('.edit-delete, .delete-add-modal').removeClass('hide') 171 var td_deletes = $(this).parent().prevAll() 172 $('.delete-add-modal input[name="edit_delete_id"]').val(td_deletes[2].innerText) 173 174 175 }) 176 177 $('#delete_cancel').click(function () { 178 $('.edit-delete, .delete-add-modal').addClass('hide') 179 $('.delete-add-modal input[name="edit_delete_id"]').val(0) 180 }) 181 182 }) 183 184 185 </script> 186 {% endblock %}
edit-teacher.html

1 {% extends 'layout.html' %} 2 3 {% block css %} 4 <style> 5 .tag{ 6 display: inline-block; 7 background-color: white; 8 color: black; 9 cursor: pointer; 10 } 11 </style> 12 {% endblock %} 13 14 15 {% block content %} 16 <h1>编辑老师</h1> 17 <form action="/edit/teacher-{{ obj.id }}/" method="POST"> 18 <input style="display: none;" type="text" id="{{ obj.id }}" value="{{ obj.id }}"> 19 <p> 20 老师姓名:<input type="text" name="name" value="{{ obj.name }}"> 21 </p> 22 <p> 23 老师学科:<input type="text" name="program"> 24 </p> 25 <p> 26 老师电话:<input type="text" name="phone"> 27 </p> 28 <p>所有班级: 29 <select name="cls" multiple> 30 {% for cls in cls_list %} 31 {% if cls.nid in id_list %} 32 <option value="{{ cls.nid }}" selected="selected">{{ cls.cls }}</option> 33 34 {% else %} 35 <option value="{{ cls.nid }}">{{ cls.cls }}</option> 36 {% endif %} 37 {% endfor %} 38 </select> 39 40 <p> 41 所带班级: 42 <select name="teacher_cls" class="remove_cls" multiple> 43 {% for i in obj_cls_list %} 44 <option value="{{ i.0 }}">{{ i.1 }}</option> 45 {% endfor %} 46 </select> 47 48 <a id="remove" > → </a> 49 <span hidden>上面为减少,下面为增加</span> 50 <a id="add" > ← </a> 51 52 未带班级: 53 <select class="add_cls" multiple> 54 {% for i in cls_exclude_list %} 55 <option value="{{ i.nid }}">{{ i.cls }}</option> 56 {% endfor %} 57 </select> 58 </p> 59 60 61 </p> 62 63 64 65 <p> 66 <input id="submit_form" type="submit" value="提交"> 67 </p> 68 69 </form> 70 {% endblock %} 71 72 {% block js %} 73 <script> 74 $(function () { 75 $('#menu_teacher').addClass('active') 76 }) 77 78 $('#submit_form').click(function () { 79 $('.remove_cls').children().each(function () { 80 // 让下面的所有的select全选中 81 // alert(123) 82 $(this).prop('selected',true) 83 }) 84 }) 85 86 87 88 $('#remove').click(function () { 89 var options = $('.remove_cls')[0].selectedOptions 90 /* 91 $.each(options,function (k,v) { 92 $(v).appendTo('.add_cls') 93 }) 94 这个类似于for循环,但是会剩下最后一个拿不过去,改为以下代码 95 同时当点击提交时会要绑定个事件:把所带班级的select都变为true,后台才能获取全部数据 96 */ 97 while (options.length>0){ 98 $(options[0]).appendTo('.add_cls') 99 } 100 101 102 }) 103 104 $('#add').click(function () { 105 var options = $('.add_cls')[0].selectedOptions 106 /* 107 $.each(options,function (k,v) { 108 $(v).appendTo('.add_cls') 109 }) 110 这个类似于for循环,但是会剩下最后一个拿不过去,改为以下代码 111 */ 112 while (options.length>0){ 113 $(options[0]).appendTo('.remove_cls') 114 } 115 116 117 }) 118 119 </script> 120 {% endblock %}
index.html

1 {% extends 'layout.html' %} 2 3 {% block css %} 4 5 {% endblock %} 6 7 {% block content %} 8 <h1>欢迎来到管理中心</h1> 9 {% endblock %} 10 11 {% block js %} 12 13 {% endblock %}
student.html

1 {% extends 'layout.html' %} 2 3 {% block css %} 4 5 {% endblock %} 6 7 8 {% block content %} 9 <h1>学生列表</h1> 10 {% endblock %} 11 12 {% block js %} 13 <script> 14 $(function () { 15 $('#menu_student').addClass('active') 16 }) 17 </script> 18 {% endblock %}
teacher.html

1 {% extends 'layout.html' %} 2 3 {% block css %} 4 <style> 5 .tag{ 6 display: inline-block; 7 background-color: white; 8 color: black; 9 cursor: pointer; 10 } 11 </style> 12 {% endblock %} 13 14 15 {% block content %} 16 <ul> 17 {% for i in li %} 18 {{ i }} 19 {% endfor %} 20 </ul> 21 22 <ul> 23 {% for k in dict_list %} 24 <li>{{ k }}</li> 25 {% endfor %} 26 </ul> 27 28 <ul> 29 {% for k in dict_list.keys %} 30 <li>{{ k }}</li> 31 {% endfor %} 32 </ul> 33 <ul> 34 {% for k in dict_list.values %} 35 <li>{{ k }}</li> 36 {% endfor %} 37 </ul> 38 <ul> 39 {% for k,v in dict_list.items %} 40 <li>{{ k }}-{{ v }}</li> 41 {% endfor %} 42 </ul> 43 44 <ul> 45 {% for i in tuple %} 46 {{ i }} 47 {% endfor %} 48 </ul> 49 50 <h1>老师列表</h1> 51 <a href="/add/teacher/">添加</a> 52 <table border="1"> 53 <thead> 54 <tr> 55 <th>ID</th> 56 <th>教师姓名</th> 57 <th>所带班级</th> 58 <th>操作</th> 59 </tr> 60 </thead> 61 62 <tbody> 63 {% for obj in teacher_list.values %} 64 <tr> 65 <td>{{ obj.nid }}</td> 66 <td>{{ obj.name }}</td> 67 <td> 68 {% for i in obj.cls_list %} 69 <span nid="{{ i.nid }}">{{ i.nid }}-{{ i.cls }}</span> 70 {% endfor %} 71 </td> 72 <td> 73 <a href="/edit/teacher-{{ obj.nid }}/">编辑</a> 74 </td> 75 </tr> 76 77 78 {% endfor %} 79 </tbody> 80 </table> 81 {% endblock %} 82 83 {% block js %} 84 <script> 85 $(function () { 86 $('#menu_teacher').addClass('active') 87 }) 88 89 90 </script> 91 {% endblock %}
六、总结
models
class UserInfo(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=16)
email = models.CharField(max_length=32)
pwd = models.CharField(max_length=16)
ctime = models.DateTimeField(auto_now_add=True)
class News(models.Model):
title = models.CharField(max_length=64)
ctime = models.DateTimeField(auto_now_add=True)
favor_count = models.IntegerField(default=0)
N2U = models.ManyToManyField(to='UserInfo')
comment_count = models.IntegerField(default=0)

1 def index(request): 2 3 4 # A.正向 5 # 查询 filter拿到的是集合 get拿到的是一条记录 6 ''' 7 filter和get的区别 8 filter拿到的是QuerySet集合包裹的条件对象【一行记录放在集合中】,用first()能等于get 9 get拿到的是条件对象【一行记录】 10 news_obj = models.News.objects.get(id=1) # News object (1)---> id=1 的一条记录 11 print(news_obj.title) 12 user_obj = news_obj.N2U.all() # <QuerySet [<UserInfo: UserInfo object (1)>]> 13 print(user_obj) 14 15 16 news_obj = models.News.objects.filter(id=1) # <QuerySet [<News: News object (1)>]> ---> id=1 的一条记录放在QuerySet中 17 news_obj = models.News.objects.filter(id=1).first() # ---> id=1 的一条记录 18 print(news_obj.title) 19 ''' 20 21 ''' 22 news_obj = models.News.objects.get(id=1) 23 user_list = news_obj.N2U.all() # <QuerySet [<UserInfo: UserInfo object (1)>]> 24 print(user_list.first().name) 25 26 news_obj = models.News.objects.filter(id=1).first() 27 user_list = news_obj.N2U.all() 28 print(user_list.first().name) 29 ''' 30 31 ''' 32 news_obj = models.News.objects.get(id=1) 33 user_list = news_obj.N2U.filter(nid=1) # <QuerySet [<UserInfo: UserInfo object (1)>]> 34 print(user_list.first().name) 35 user_list = news_obj.N2U.get(nid=1) # UserInfo object (1) 36 print(user_list.name) 37 ''' 38 39 ''' 40 # 插入数据 add 41 news_obj = models.News.objects.get(id=1) 42 user_list = news_obj.N2U.all() 43 for obj in user_list: 44 print('before',obj.name) 45 user_obj = models.UserInfo.objects.get(nid=2) # 拿到一行记录 46 news_obj.N2U.add(user_obj) # 插入一行记录 47 48 news_obj.N2U.add(3) # 插入主键数字,也能插入 49 news_obj.N2U.add(*[2,4]) # 通过列表插入多个记录 50 51 user_obj = models.UserInfo.objects.get(name='eric') # 通过名字拿到一行记录 52 news_obj.N2U.add(user_obj) # 插入拿名字的一行记录 53 54 user_list = news_obj.N2U.all() 55 for obj in user_list: 56 print('after',obj.name) 57 58 ''' 59 60 ''' 61 # 删除数据 remove clear 62 news_obj = models.News.objects.get(id=1) 63 user_obj = models.UserInfo.objects.get(nid=2) 64 news_obj.N2U.remove(user_obj) 65 list = news_obj.N2U.all() 66 for item in list: 67 print(item.nid) 68 69 news_obj = models.News.objects.get(id=1) 70 news_obj.N2U.remove(4) # 通过删除数字,也能成功 71 for item in list: 72 print(item.nid) 73 74 news_obj = models.News.objects.get(id=1) 75 news_obj.N2U.clear() # 清空所有与id=1这条新闻有关的所有用户 76 77 78 # 修改数据 set 79 news_obj = models.News.objects.get(id=1) 80 news_obj.N2U.set([2,4]) # 清除之前id=1新闻相关的用户,重新加入2,4用户 81 ''' 82 83 # B.反向 84 # 查询 用news_set进行反向操作 85 user_obj = models.UserInfo.objects.get(nid=1) 86 user_obj.news_set.get(id=2) 87 print(user_obj.news_set.get(id=2).title) 88 # 插入 add 89 user_obj = models.UserInfo.objects.get(nid=3) 90 news_obj = models.News.objects.get(id=1) 91 user_obj.news_set.add(news_obj) 92 user_obj.news_set.add(2) 93 # 删除 remove clear 94 user_obj = models.UserInfo.objects.get(nid=3) 95 news_obj = models.News.objects.get(id=1) 96 user_obj.news_set.remove(news_obj) 97 user_obj.news_set.clear() 98 # 修改 set 99 user_obj = models.UserInfo.objects.get(nid=2) 100 user_obj.news_set.set([2]) 101 102 103 104 # 跨表反向查询(在ManyToManyField中加入related_name或related_query_name) 105 # user_obj = models.objects.get(id=1) 106 # user_obj.news_set # 未加 107 108 # user_obj.n.name 加上related_name='n'后就能直接以n反向 109 # user_obj.n1_set.name 加上related_query_name='n1'后直接这样反向查询 110 111 112 113 114 return HttpResponse('ok')