第七单元 ORM表关系及操作

多对一关系

`Django`使用`django.db.models.ForeignKey`定义多对一关系。
多对一关系是指一个表内的数据配对另一个表的数据 另个表中的多个数据可共同指向这一数据
	# to:后边写所关联的模型类  
    # on_delete=models.CASCADE:主表中数据删除,从表也删除
    # 外键关联的是整个模型类,不是单独的某一个对象
    # 但是通过模型类会产生一个相关联的字段  字段名_id
 teacher = 		models.ForeignKey(to=Teacher,on_delete=models.CASCADE,verbose_name="所属老师")
将老师分配个班级之后,由于班级表关联了老师字段,我们可以通过班级找到对应老师
虽然老师表中没有关联班级字段,但是也可以通过老师找到他所带的班级,这种查询方式也叫作关联查询
语言语法
CASCADE删除主表数据的同时删除外键表中数据
PROTECT抛出ProtectedError异常,阻止删除主表中被外键应用的数据
SET_NULL为NULL,只能在字符null=True用
SET_DEFAULT设置默认的值

多对一的反向查询

通过模型类名称后追加一个_set,来实现反向查询

反向查询:通过django的内置属性来进行查询  模型类(模型类小写)_set()可以反向查询老师名下的所有学生,
    # 查询id为1的老师的所有学生    --先找到id为1的老师    
    tea = Teacher.objects.get(id=1)    
    --查询tea老师名下的所有学生  老师对象.模型类_set.all()    
    tea.student_set.all()

一对一关系是什么

模型类使用`OneToOneField`用来定义一对一关系;
OneToOneField(to, on_delete, parent_link=False, options)
class Teacher(models.Model):
    name = models.CharField(max_length=50)
    age = models.CharField(max_length=50)
    def __str__(self):
        return self.name
class Professor(models.Model):
    teacher = models.OneToOneField(Teacher,primary_key=True,on_delete=models.CASCADE)
    big_project = models.CharField(max_length=50)
    def __str__(self):
        return self.teacher.name

一对一关系的增删改操作

>>> t1 = Teacher.objects.create(name='Jack',age='22')
>>> t2 = Teacher.objects.create(name='Bob',age='17')
>>> p1 = Professor.objects.create(teacher=t1,big_project='雾霾净化术')
>>> p1.teacher
<Teacher: Jack>
>>> p1.teacher = t2
#   保存
>>> p1.save()

一对一关系正向查询

# 正向查询:通过教授,查询对应的讲师信息
>>> p1.teacher
<Teacher: Bob>

一对一关系反向查询

# 反向查询:通过讲师,查询教授信息, 反向查询时,只需要 模型类 本身即可
t1.professor.name

多对多关系

多对多关系在模型中使用`ManyToManyField`字段定义
# 在多对多的情况,有专门的第三张表,存储 对应关系, 表本身并没有字段来存储对应关系,此时删除任意数据,不影响另一张表数据
所以不需要on_delete属性
django.db import models
# 一个乐队可以有很多音乐家,一个音乐家也可以隶属好多个乐队
# 定义音乐家模型类
class Artist(models.Model):    
    artist_name = models.CharField(max_length=20,verbose_name="音乐家名字")
    #     定义元类    
    class Meta:        
        db_table = "artist1"    
    def __str__(self):        
        return self.artist_name
    # 定义乐队模型类
    class Band(models.Model):    
        band_name = models.CharField(max_length=20,verbose_name="乐队名")    
        # 多对多    
        artist = models.ManyToManyField(Artist)    
        # 定义元类    
        class Meta:        
            db_table = "band"    
        def __str__(self):        
            return self.band_name

多对多关系的外键添加操作

添加音乐家语法:
    模型类.objects.create()
    a1 = Artist.objects.create(artist_name="朗朗")
    a2 = Artist.objects.create(artist_name="李健")
添加乐队语法:
    语法:
    b1 = Band.objects.create(band_name="破吉他乐队")
    b2 = Band.objects.create(band_name="凯乐乐队")
    
# b1这个乐队有2个音乐家分别是a1和a2  将a1和a2添加到b1这个乐队里
b1.artist.add(a1,a2)
# b2这个乐队有一个音乐家是a2
b2.artist.add(a2)

多对多关系的外键移除操作

# 接触a1和b1的关系   在b1乐队中将a1解除  只是接触乐队和音乐家的关系不是删除数据
b1.artist.remove(a1)

多对多关系的修改和查询

# 通过外键查询该乐队的全部音乐家
# 查看b1乐队的成员
b1.artist.all()
# 查看b2乐队的成员
b2.artist.all()

# 反向查询:通过音乐家,查询该音乐家加入的乐队信息
# 查看a2这个音乐家所属的乐队
a2.band_set.all()

实例

from django.shortcuts import render,redirect
from django.views import View
from django.http import HttpResponse
from teacher.models import Teacher,Student


# Create your views here.
# 展示所有老师信息
class TeacherView(View):
    def get(self,request):
        # 获取老师表的所有信息
        teachers = Teacher.objects.all()
                                                # 传递数据需要使用字典格式
        return render(request,'teachers.html',{"teachers":teachers})

# 获取老师所对应的学生
class StudentView(View):
    def get(self,request,id):
        # 通过老师的id进行过滤
        students = Student.objects.filter(teacher_id=id)
        return render(request,'students.html',{'students':students})

# 点击删除删除对应的数据
class DelstuView(View):
    def get(self,request,id):
        # 1.删除数据后返回教师页面
        # 获取学生的id进行删除
        # Student.objects.filter(id=id).delete()
        # return redirect(f'/teacher/')

        # 2.删除数据,并重定向导学生页面
        # 先找到学生的信息
        student_data = Student.objects.get(id=id)
        # 然后获取到对应学生的老师id
        tea_id = student_data.teacher_id
        # 将学生信息删除
        student_data.delete()
        # 返回到对应老师id的学生表
        return redirect(f'/stu/{tea_id}/')


# 修改数据
class UpdateStudentView(View):
    def get(self,request,id):
        try:
            # 获取需要修改的数据
            student_data = Student.objects.get(id=id)
        except Exception as e:
            print(e)
            return HttpResponse("要修改的数据不存在")
        # 将数据传递到修改页面用于展示
        return render(request,'update.html',{'student':student_data})

    def post(self,request,id):
        # 将学生页面输入的数据获取
        name = request.POST.get("name")
        height = request.POST.get("height")
        face = request.POST.get("face")
        teacher = request.POST.get("teacher")
        try:
            # 过滤对应id的数据进行修改
            Student.objects.filter(id=id).update(
                stu_name=name,
                height=height,
                face=face,
                teacher=teacher,
            )
        except Exception as e:
            print(e)
            return HttpResponse("修改数据失败")
        # 回到学生页面
        return redirect('/stu/')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值