Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
django mvc模型_零基础学编程应该从哪入手,希望能够帮助你!!!。
今天是2019年2月20日,小叮当来继续为大家分享Django的干货~
主要内容有:表的级联删除、表关联对象的访问、表关联对象的补充、关系表的数据操作和多表查询。
首先,我们接着昨天所建的项目db_test,为其配置路由
(1)为db_test新建urls.py文件
(2)在主路由中为db_test分配子路由
(3)设置db_test的views.py定义视图函数
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' from django.shortcuts import render # Create your views here. from django.http import HttpResponse #导入学院表、学生表、学生详细信息表、课程表 from .models import Department,Student,Stu_detail,Course def test(request): Department.objects.create(d_name='计算机') Department.objects.create(d_name='音乐') Department.objects.create(d_name='艺术') Department.objects.create(d_name='金融') Department.objects.create(d_name='英语') Student.objects.create(s_name='小叮当',department_id=1) Student.objects.create(s_name='少年叮当', department_id=2) Student.objects.create(s_name='青年叮当', department_id=3) Student.objects.create(s_name='任性叮当', department_id=4) Student.objects.create(s_name='国外叮当', department_id=5) return HttpResponse('小叮当在往学院表和学生表里建数据')
(4)在db_test的urls.py中配置对应的路由
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' from django.urls import path from . import views urlpatterns = [ path('test/',views.test), ]
(5)在浏览器中访问
(6)通过xshell进行查看
可以看到,学院表和学生表已成功创建。
一、表的级联删除
(1)在主表中删除数据,对应表中的数据也会被删除。
例如,将学院表中的计算机学院删除,对应学生表中属于计算机学院的小叮当则也会被删除。
重新定义db_test中views.py里的视图函数test
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' from django.shortcuts import render # Create your views here. from django.http import HttpResponse #导入学院表、学生表、学生详细信息表、课程表 from .models import Department,Student,Stu_detail,Course def test(request): Department.objects.get(d_id=1).delete() return HttpResponse('小叮当将学院表中id=1的学院删除了')
在浏览器中访问,使视图函数运行
通过xshell查看数据库
可见计算机学院从学院表中删除后,与之关联的学生表中的小叮当也被删除了。
(2)设置默认值为空的级联删除
当我们进行级联删除时,只想删除主表中的数据以及其他表对它的引用,而不删除其他表中的数据时,该怎么做呢?
例如,我想删除学院表中id=2的音乐学院和学生表中对音乐学院的引用,而不删除学生表中的少年叮当
首先,我们可以在xshell中进入mysql
执行 show create table db_test_student\G 查看创建db_test_student表的mysql语句 "\G"表示结果按列输出
可以看到,department_id不允许为空
我们在models.py中更改表结构,将学生信息表中的on_delete其设置为默认值为空的级联删除
具体代码如下:
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' #2.创建学生信息表 class Student(models.Model): s_id = models.AutoField(primary_key=True) s_name = models.CharField(max_length=30) #实现一对多关系ForeignKey 其中on_delete使用默认值为空的级联删除 department = models.ForeignKey('Department',on_delete=models.SET_NULL,null=True)
(当然,如果不想执行级联删除,可以on_delete=models.PROTECT 将其保护起来)
更改表结构后,执行映射等操作。
在Tools中找到Run manage.py Task...
执行makemigrations
执行migrate
之后在xhell的mysql中再次查看表结构,发现department_id字段已默认为空
重新定义db_test中views.py里的视图函数test
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' from django.shortcuts import render # Create your views here. from django.http import HttpResponse #导入学院表、学生表、学生详细信息表、课程表 from .models import Department,Student,Stu_detail,Course def test(request): Department.objects.get(d_id=2).delete() return HttpResponse('小叮当将学院表中id=2的学院删除了')
在浏览器中访问
通过xshell查看数据库
二、表关联对象的访问
1.一对多关联 学院表和学生表
(1)在models.py中重新定义模型类,为学院表和学生表加上自定义输出def __str__(self)
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' #1.创建学院信息表 class Department(models.Model): d_id = models.AutoField(primary_key=True) d_name = models.CharField(max_length=30) def __str__(self): return 'Department<d_id=%s,d_name=%s>' % (self.d_id,self.d_name) #2.创建学生信息表 class Student(models.Model): s_id = models.AutoField(primary_key=True) s_name = models.CharField(max_length=30) #实现一对多关系ForeignKey 其中on_delete为必填字段使用级联删除CASCADE department = models.ForeignKey('Department',on_delete=models.CASCADE,null=True) def __str__(self): return 'Students<s_id=%s,s_name=%s,department_id=%s>'%(self.s_id,self.s_name,self.department_id)
(2)重新定义视图函数
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' def test(request): d1 = Department.objects.get(d_id=3) #一个学院类的实例对象 s1 = Student.objects.get(s_id=3)#一个学生类的实例对象 print(s1.department,type(s1.department))#学生所属学院 print(s1.department.d_name)#学生所属学院的名称 stu=d1.student_set.all() #学院里所属的学生(反向查询) print(stu) return HttpResponse('小叮当在进行表关联对象的访问')
(3)在浏览器中访问
(4)在后台查看输出
小结:在学生表查询到的学生信息相当于学生类的实例对象,可以直接像访问成员函数那样访问学院类中的属性,以此来实现表关联对象的访问。
值得注意,学生表关联了学院表,想查询学院有哪些学生时就属于反向查询了。
反向查询
(1)直接反向查询
直接反向查询,是通过查询关键字加”_set"来实现的,例如“student_set",如果表关系是一对一,则不加_set也可。
(2)重命名查询 related_name
通过在模型类中添加related_name的方法,也可进行反向查询
具体代码如下
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' #2.创建学生信息表 class Student(models.Model): s_id = models.AutoField(primary_key=True) s_name = models.CharField(max_length=30) #实现一对多关系ForeignKey 其中on_delete为必填字段使用级联删除CASCADE department = models.ForeignKey('Department',on_delete=models.CASCADE,related_name='students') def __str__(self): return 'Students<s_id=%s,s_name=%s,department_id=%s>'%(self.s_id,self.s_name,self.department_id)
此时进行反向查询时,使用students即可。因为系统中已经没有了student_set属性,若还按student_set查询则会报错
在视图函数中改为用students查询,即可成功查询
2.一对一关联 学生表和学生详细表
(1)查看学生信息详细表 和学生表
(2)models.py中在学生详细模型类中自定义输出 def__str__(self)
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' #4.学生详细信息表 class Stu_detail(models.Model): # 实现一对一关系OneToOneField 其中on_delete为必填字段使用级联删除CASCADE student = models.OneToOneField('Student',on_delete=models.CASCADE) age = models.IntegerField() gender = models.BooleanField(default=1) city = models.CharField(max_length=30,null=True) def __str__(self): return 'Stu_detail<s_id=%s,age=%s,gender=%s,city=%s>'%(self.student_id,self.age,self.gender,self.city)
(3)views.py中根据表字段创建数据表
由于学生详细信息表关联的是学生表,所以在创建学生详细表时,id要从学生表里现在有的”2、3、4、5“中创建。
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' from django.shortcuts import render # Create your views here. from django.http import HttpResponse #导入学院表、学生表、学生详细信息表、课程表 from .models import Department,Student,Stu_detail,Course def test(request): Stu_detail.objects.create(age=18,gender=0,city='洛阳',student_id=3) return HttpResponse('小叮当在创建学生详细信息表')
在浏览器中访问触发视图函数
在数据库中查看
(4)重新定义视图函数
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' from django.shortcuts import render # Create your views here. from django.http import HttpResponse #导入学院表、学生表、学生详细信息表、课程表 from .models import Department,Student,Stu_detail,Course def test(request): std = Stu_detail.objects.get(id=1) #一个学生的详细信息 print(std.student.s_name) #正向查询 print(s1.stu_detail) #反向查,直接类名小写 return HttpResponse('小叮当在实现一对一表关系的对象访问')
(5)在浏览器中访问
(6)在后台查看
3.多对多关联 学生表和课程表
(1)查询课程表字段
根据字段在views.py中为课程表添加数据
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' from django.shortcuts import render # Create your views here. from django.http import HttpResponse #导入学院表、学生表、学生详细信息表、课程表 from .models import Department,Student,Stu_detail,Course def test(request): Course.objects.create(c_name='Python') Course.objects.create(c_name='自然语言处理') Course.objects.create(c_name='养猪') Course.objects.create(c_name='推塔与补兵') Course.objects.create(c_name='如何对线') Course.objects.create(c_name='摄影') return HttpResponse('小叮当在创建课程表')
在浏览器中访问
在数据库中查看
在models.py中为课程表自定义输出 def __str__(self)
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' #3.课程信息表 class Course(models.Model): c_id = models.AutoField(primary_key=True) c_name = models.CharField(max_length=30) student = models.ManyToManyField('Student') def __str__(self): return 'Course<c_id=%s,c_name=%s>'%(self.c_id,self.c_name)
由于访问方法和之前的一样,这里不再演示,在views.py中定义代码如下
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' s4 = Student.objects.get(s_id=4) #一个学生的实例 c1 = Course.objects.get(c_id=1) #一个课程的实例 print(c1.student.all()) #正向查询 #print(s4.course_set.all()) #反向查询 默认的是course_set print(s4.courses.all()) #related_name 指定名字为courses
三、表关联对象的补充
在表关联中的正向查询是指,一个表的模型类可以在另个一表的模型类中找到。
例如,在课程表的模型类中可以直接访问到学生表模型类
那么,查询一门课程所选的学生就是正向查询。反之查询学生选了哪些课就是反向查询。
四、关系表的数据操作
1.数据的添加
(1)一对多关系 add()添加已经存在的数据 create()添加新的数据
在views.py中重新定义视图函数
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' def test(request): d3 = Department.objects.get(d_id=3) s3 = Student.objects.get(s_id=3) std = Stu_detail.objects.get(id=1) c1 = Course.objects.get(c_id=1) sn_xdd = Student.objects.get(s_id=2) #一对多关系 数据的添加 add() 添加的数据首先已存在 d3.students.add(sn_xdd) gw_xdd = Student.objects.get(s_id=5) #如果原有学生已有所属学院 add则可起到修改的作用 #将s_id=5的学生所属院改为d_id=3的学院 d3.students.add(gw_xdd) #新建数据 create() d3.students.create(s_name='测试小叮当1') d3.students.create(s_name='测试小叮当2') return HttpResponse('小叮当在进行一对多关系表的数据添加')
在浏览器中访问触发视图函数
在数据库中查看
(2)多对多关系 add()添加已经存在的数据 create()添加新的数据
在views.py中重新定义视图函数
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' def test(request): d3 = Department.objects.get(d_id=3) s3 = Student.objects.get(s_id=3) std = Stu_detail.objects.get(id=1) c1 = Course.objects.get(c_id=1) sn_xdd = Student.objects.get(s_id=2) # #一对多关系 数据的添加 add() 添加的数据首先已存在 # d3.students.add(sn_xdd) gw_xdd = Student.objects.get(s_id=5) '''多对多''' c2 = Course.objects.get(c_id=2) #添加 3号学生选了1号和2号课程 s3.courses.add(c1,c2) #新建 学院为3号学生开设了英雄联盟课程 s3.courses.create(c_name='英雄联盟') return HttpResponse('小叮当在进行多对多关系表的数据添加')
在浏览器中访问 触发视图函数
在数据库中查找课程表、课程-学生中间信息表
2.数据删除 remove() 和clear()
(1)remove()
一对多关系的表使用remove删除时,必须保证外键列允许为空
例如,学院表和学生的对应关系
多对多关系,使用remove删除,删除掉的是中间信息表
在视图函数中定义
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' def test(request): d3 = Department.objects.get(d_id=3) s3 = Student.objects.get(s_id=3) std = Stu_detail.objects.get(id=1) c1 = Course.objects.get(c_id=1) sn_xdd = Student.objects.get(s_id=2) gw_xdd = Student.objects.get(s_id=5) c2 = Course.objects.get(c_id=2) d3.students.remove(sn_xdd) s3.courses.remove(c1,c2) return HttpResponse('小叮当在使用remove进行关系表的数据删除')
在浏览器中访问
在数据库中查询
(2)clear()进行清空
使用print查看3号学生选了哪些课程
定义视图函数
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' def test(request): s3 = Student.objects.get(s_id=3) print(s3.courses.all()) return HttpResponse('小叮当在查看3号学生的选课')
浏览器中访问
后台中查看
定义视图函数使用clear
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' def test(request): s3 = Student.objects.get(s_id=3) print(s3.courses.all()) s3.courses.clear() return HttpResponse('小叮当使用clear清除了3号学生的选课')
浏览器中访问
后台查询
数据库中查询中间课程-学生信息表
可见,clear()会将符合条件的数据全部清空0
五、多表查询
多表查询又被称为是跨关联关系的查询。
Django 提供一种强大而又直观的方式来“处理”查询中的关联关系,它在后台自动帮你处理JOIN。 若要跨越关联关系,只需使用关联的模型字段的名称,并使用双下划线分隔,直至你想要的字段。
1.重建学生选课数据
在views.py中重新定义视图函数
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' def test(request): d3 = Department.objects.get(d_id=3) s3 = Student.objects.get(s_id=3) std = Stu_detail.objects.get(id=1) c1 = Course.objects.get(c_id=1) sn_xdd = Student.objects.get(s_id=2) # #一对多关系 数据的添加 add() 添加的数据首先已存在 # d3.students.add(sn_xdd) gw_xdd = Student.objects.get(s_id=5) '''多对多''' c2 = Course.objects.get(c_id=2) #添加 3号学生选了1号和2号课程 s3.courses.add(c1,c2) #新建 学院为3号学生开设了英雄联盟课程 s3.courses.create(c_name='英雄联盟') return HttpResponse('小叮当在进行选课数据的重建')
在浏览器中访问 触发视图函数
在数据库中查看
2.进行多表查询
在views.py中重新定义视图函数
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'IT小叮当' __time__ = '2019-02-19 15:21' def test(request): #1.查询学院名字为'艺术’的学生信息 ds = Student.objects.filter(department__d_name='艺术') print('查询1',ds) #2.查询学生名字中包含‘测试’的学生的学院信息 sd=Department.objects.filter(students__s_name__contains='测试') print('查询2',sd) #3.查询学号为3的学生的所有课程 sc = Course.objects.filter(student__s_id=3) print('查询3',sc) #4.查询报了课程1的所有学生的信息 cs = Student.objects.filter(courses__c_id=1) print('查询4',cs) #5.查询报了python课程的学生的所属学院信息 psd = Department.objects.filter(students__courses__c_name= 'python') print('查询5',psd) return HttpResponse('小叮当在进行多表查询')
在浏览器中查看
在后台查看
对照数据库进行检验
经检查查询结果正确,可见Django的多表查询结果是十分便捷的了。
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
下一篇
已是最新文章