• Django ORM深度游:探索多对一、一对一与多对多数据关系的奥秘与实践


    在这里插入图片描述

    系列文章目录



    前言

        在Django开发中,数据关系的管理至关重要。今天,我们将快速了解Django ORM如何处理多对一、一对一和多对多这三种核心数据关系。这些基础知识将帮助你更高效地构建数据库驱动的应用。让我们一起探索Django ORM的奥秘吧!


    一、多对一关系

    1.多对一关系是什么

    Django使用django.db.models.ForeignKey定义多对一关系。

    博客表—用户表 - - - 多对一

    # app/model.py
    class UserModel(models.Model):
        name = models.CharField(max_length=50)
        age = models.IntegerField()
        height = models.DecimalField(max_digits=3, decimal_places=2)
        def __str__(self):
            return self.name
        class Meta:
            db_table = 'users'
    
    
    class BlogModel(models.Model):
        title = models.CharField(max_length=100)
        content = models.TextField()
        pub_date = models.DateField()
        address = models.CharField(max_length=50)
        user = models.ForeignKey(to=UserModel, on_delete=models.CASCADE)
        def __str__(self):
            return self.title
        class Meta:
            db_table = 'blogs'
    

    2.多对一关系的增删改操作

    增:

        # 1.添加user
        u1 = UserModel.objects.create(name="王五", age=18, height=1.78)
    
        # 2.为 id(pk) = 1的用户添加blog
        u2 = UserModel.objects.get(pk=1)
        blog = BlogModel()
        blog.title = "ORM关联模型"
        blog.content = "多对一、一对一、多对多模型"
        blog.pub_date = "2024-05-31"
        blog.address = "csdn"
        blog.user = u2
        blog.save()
    

    改:

        # 1.修改用户信息
        # u3 = UserModel.objects.get(id=1)
        # u3.age = 100
        # u3.save()
        # 2.修改博客信息
        # b3 = BlogModel.objects.get(id=9)
        # b3.address = "修改后的CSDN地址"
        b3 = BlogModel.objects.filter(id=9).update(address="再修改(update)后的CSDN地址")
    
        # b3.save()
    

    删:

        # 1.删除blog表中的记录,直接删除
        # blog = BlogModel.objects.get(pk=10)
        # blog.delete()
        # 2.删除user表中数据,此user对应的blog也会删除
        u4 = UserModel.objects.get(pk=2)
        u4.delete()
    

    3.多对一的正向查询

    	# 多查询一的情况下,直接通过模型类中的外键关联字段查询
        # 正向查询
        b5 = BlogModel.objects.get(user_id=1)
        print(b5)
        print(b5.user.name)
        print(b5.user.age)
        print(b5.user.height)
    >>>ORM关联模型
    >>>张安
    >>>100
    >>>1.96  
    

    4.多对一的反向查询

        # 反向查询:主表通过blogmodel_set查从表
        u6 = UserModel.objects.get(id=1)
        print(u6)
        b6 = u6.blogmodel_set.all()
        print(b6)
        for blog in b6:
            print(blog.title)
            print(blog.content)
    

    二、一对一关系

    1.一对一关系是什么

    模型类使用OneToOneField用来定义一对一关系;

    学生表与学生信息表 - - - 一对一
    models.CASCADE:多表关联, 删除数据的时候 一删就全删

    #app/model.py
    class StudentModel(models.Model):
        name = models.CharField(max_length=50)
        age = models.IntegerField()
        height = models.DecimalField(max_digits=3, decimal_places=2)
        def __str__(self):
            return self.name
        class Meta:
            db_table = 'students'
    
    
    class StuDetail(models.Model):
        address = models.CharField(max_length=50)
        idcard = models.CharField(max_length=50)
        outlook = models.CharField(max_length=50)
        student = models.OneToOneField(to=StudentModel, on_delete=models.CASCADE)
        def __str__(self):
            return self.idcard
        class Meta:
            db_table = 'detail'
    

    其中,ON DELETEON UPDATE 表示事件触发限制,各参数意义如下:

    参数意义
    RESTRICT限制外表中的外键改动(默认值,也是最安全的设置)
    CASCADE跟随外键改动
    SET NULL设为null值
    NO ACTION无动作
    SET DEFAULT设为默认值

    2.一对一关系的增删改操作

    增:

        # 1.增加学生 Student
         st1 = StudentModel()
         st1.name = "张三三"
         st1.age = 18
         st1.height = 1.79
         st1.save()
    
        # 2.增加学生信息 StuDetail
         sd1 = StuDetail()
         sd1.address = "北京"
         sd1.idcard = 123
         sd1.outlook = '团员'
         sd1.student = st1
         sd1.save()
    

    改:

        # 3.修改 学生详细信息
        sd2 = StuDetail.objects.get(id=1)
        sd2.address = "我在中东吃炸鸡"
        sd2.save()
    
        # 4.修改 学生信息
        st2 = StudentModel.objects.get(id=1)
        st2.age = 12
        st2.save()
    

    删:

        # 5.删除
         st5 = StudentModel.objects.get(id=1)
         st5.delete()
    

    3.一对一关系正向查询

        # 5.正向查询:
        sd3 = StuDetail.objects.get(id=1)
        print(sd3.address)
        print(sd3.idcard)
        print(sd3.outlook)
        print(sd3.student.name)
        print(sd3.student.age)
    

    4.一对一关系反向查询

    	# 6.反向查询:
        st4 = StudentModel.objects.get(id=1)
        print(st4.name)
        print(st4.age)
        print(st4.studetail.address)
        print(st4.studetail.idcard)
        print(st4.studetail.outlook)
        
        #print(stu.blogmodel_set.all())
        #注意:这是错误的,一对一没有_set,且全通过小写字段(eg:studetail,blogmodel_set)找到类名
    	 
    

    三、多对多关系

    1.多对多关系是什么

    多对多关系在模型中使用ManyToManyField字段定义

    多对多关系可以是具有关联,也可以是没有关联,所以不需要明确指定on_delete属性
    原因:在多对多的情况,有专门的第三张表,存储 对应关系, 表本身并没有字段来存储对应关系,此时删除任意数据,不影响另一张表数据

    电影表与演员表 - - - 多对多

    # app/models.py
    class ActorModel(models.Model):
        name = models.CharField(max_length=50)
        age = models.IntegerField()
        gender = models.CharField(max_length=2)
        def __str__(self):
            return self.name
        class Meta:
            db_table = 'actors'
    
    
    class MovieModel(models.Model):
        name = models.CharField(max_length=50)
        mtime = models.CharField(max_length=50)
        info = models.CharField(max_length=50)
        actors = models.ManyToManyField(to=ActorModel)
        def __str__(self):
            return self.name
        class Meta:
            db_table = 'movies'
    

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

    创建:

        # 1.添加演员
        a1 = ActorModel()
        a1.name = '刘海柱'
        a1.age = 32
        a1.gender = '男'
        a1.save()
        #
        a2 = ActorModel()
        a2.name = '赵小刀'
        a2.age = 30
        a2.gender = '女'
        a2.save()
        #
        a3 = ActorModel()
        a3.name = '哈士奇'
        a3.age = 33
        a3.gender = '男'
        a3.save()
      -------------------------------------------
        # 2.添加电影信息
        m1 = MovieModel()
        m1.name = "精武门"
        m1.mtime = "2h"
        m1.info = "这是一个武打片"
        m1.save()
    
        m2 = MovieModel()
        m2.name = "ye邪不压正"
        m2.mtime = "2h30min"
        m2.info = "这肯呢个肯呢个可能是一个武打片"
        m2.save()
    
        m3 = MovieModel()
        m3.name = "don东北黑道纷纭"
        m3.mtime = "2h50min"
        m3.info = "黄及哦啊哦写"
        m3.save()
    

    增加:

    	# 3.给电影添加演员--正向的
        a1 = ActorModel.objects.get(id=1)
        a2 = ActorModel.objects.get(id=2)
        a3 = ActorModel.objects.get(id=3)
        # 给任意一个电影添加对应的演员
        m1 = MovieModel.objects.get(id=1)
        m1.actors.add(a1)
        m1.actors.add(a2)
        m1.actors.add(a3)
    ---------------------------------------------
        # 4.给演员安排几个电影拍
        m2 = MovieModel.objects.get(id=2)
        m3 = MovieModel.objects.get(id=3)
        
        a1 = ActorModel.objects.get(id=1)
        a1.moviemodel_set.add(m2,m3)
    

    3.多对多关系的外键移除工作

    多对多关联字段的删除,要使用remove来进行关系的断开
    而不是直接使用deleteremove只会断开数据之间的联系,但是不会将数据删除

        # 5.删除,会删除电影及电影-演员表中的对应关系
        # MovieModel.objects.get(id=1).delete()
    
        # 6.删除对应关系:从某电影m6中移除某演员a1,只影响演员-电影对应关系表
        m6 = MovieModel.objects.get(id=6)
        a1 = ActorModel.objects.get(id=1)
        a1.moviemodel_set.remove(m6)
    

    4.多对多关系的修改和查询

        # 7.查询数据
        # 根据任意一个电影,查询所有参演的演员-
        m1 = MovieModel.objects.get(id=1)
        print("-"*10)
        print(m1.actors.all())
        
        # 根据任意一个演员,查询拍过的所有电影 f反向查询
        a1 = ActorModel.objects.get(id=1)
        print("-"*10)
        print(a1.moviemodel_set.all())
    

    在这里插入图片描述

  • 相关阅读:
    Java之Map集合的详细解析
    echarts设置多条折线不是你想的那样简单
    LINQ to SQL语句之ADO.NET与LINQ to SQL
    远程工作面试:特殊情况下的面试技巧
    2022安洵杯babyphp
    [SWPUCTF 2021 新生赛]sql - 联合注入
    浅析基于AI智能识别技术的明厨亮灶智能化监管方案
    Java设计模式——单例模式
    HTML制作一个汽车介绍网站【大学生网页制作期末作业】(汽车首页 1页 带psd)
    【自考必看】你能学会的《信息资源管理》,计算机科学与基础(本科)
  • 原文地址:https://blog.csdn.net/m0_48173416/article/details/139359731