• Django--orm 多表外键字段的操作


    数据准备

    from django.db import models
    
    # Create your models here.
    
    # 表app01_publish
    class Publish(models.Model):
        name = models.CharField(max_length=20)
        addr = models.CharField(max_length=20)
    
    # 表app01_authordetail
    class AuthorDetail(models.Model):
        tel = models.CharField(max_length=20)
    
    # 表app01_author
    class Author(models.Model):
        name = models.CharField(max_length=20)
        age = models.IntegerField()
    
        # 表app01_author一对一表app01_authordetail
        detail = models.OneToOneField(to='AuthorDetail',to_field='id',unique=True,on_delete=models.CASCADE)
    
    
    # 表app01_book
    class Book(models.Model):
        title = models.CharField(max_length=20)
        price = models.DecimalField(max_digits=8, decimal_places=2)
        pub_date = models.DateField(auto_now_add=True)
    
        # 表app01_book多对一表app01_publish,参数to指定模型名,参数to_field指定要关联的那个字段
        publish = models.ForeignKey(to='Publish',to_field='id',on_delete=models.CASCADE)
    
        # 我们自己写sql时,针对书籍表与作者表的多对关系,需要自己创建新表,而基于django的orm,下面这一行代码可以帮我们自动创建那张关系表
        authors=models.ManyToManyField(to='Author')
        # 变量名为authors,则新表名为app01_book_authors,若变量名为xxx,则新表名为app01_book_xxx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    按照上图所示,由于foreign key的关系,我们需要事先往app01_publish与app01_authordetail里插入记录

    # 1、需求:通过模型Publish往表app01_publish里插入三家出版社
    Publish.objects.create(name='北京出版社')
    Publish.objects.create(name='长春出版社')
    Publish.objects.create(name='大连出版社')
    
    # 2、需求:通过模型AuthorDetail往表app01_authordetail里插入三条作者详情
    AuthorDetail.objects.create(tel='12345678900')
    AuthorDetail.objects.create(tel='98765432100')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    一、多表操作–外键字段

    1.1 增

    插入时会涉及到多张表,我们同样分三种情况来介绍

    一对一、一对多关系使用create()方法;多对多关系使用add()方法

    需求:书籍(葵花宝典、菊花宝典、桃花宝典)都是在北京出版社出版的

    多对一

    # 1、先通过模型Publish从出版社表app01_publish查出北京出版社
    publish_obj=Publish.objects.filter(name='北京出版社').first()
    
    • 1
    • 2

    方式一:使用publish_id参数指定关联

    在已经出版社id的情况下,可以直接指定

    models.Book.objects.create(title='葵花宝典', price=2000, publish_id=1)
    models.Book.objects.create(title='菊花宝典', price=3000, publish_id=1)
    models.Book.objects.create(title='桃花宝典', price=4000, publish_id=1)
    
    • 1
    • 2
    • 3

     

    方式二:使用publish参数指定关联

    对于外键字段也可以直接传入想要关联的外键对象,不过字段名就不是表中的的字段名,而是想要关联的表名

    models.Book.objects.create(title='三国志',price='123.99',publish=publish_obj)
    
    • 1

    一对一

    需求:插入三个作者,并与作者详情表一一对应

    注意:一对一字段是唯一对应的,不能重复

    # 方式一:需要事先过滤出作者详情的对象,然后通过模型Author的字段author来指定要关联的作者详情对象
    author_obj1 = Author.objects.filter(pk=1)
    Author.objects.create(name='egon',age=18,author = author_obj1)
    ...# 剩下的省略
    
    # 方式二:确定作者详情对象的id,然后通过模型Author通过字段author_id来指定关联关系,
    Author.objects.create(name='egon',age=18,author_detail_id=1)
    Author.objects.create(name='kevin',age=38,author_detail_id=2)
    Author.objects.create(name='rose',age=28,author_detail_id=3)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    多对多

    add()方法

    需要注意:在哪个表中创建的ManyToManyField对应的虚拟字段,那么就使用哪个表的add()方法

    方式一:根据对象添加

    在原生SQL中多对多关系涉及到操作第三张关系表,但是在ORM中我们只需要操作模型类Book下的字段author即可

    # 1、先获取书籍对象
    book_obj1=Book.objects.get(title='葵花宝典')
    
    # 2、然后获取作者对象
    lili=Author.objects.get(name='lili')
    frank=Author.objects.get(name='frank')
    
    # 3、最后依次创建上述关系:
    book_obj1.authors.add(lili,frank)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    方式二:直接传入主键值

    book_obj1=Book.objects.get(title='菊花宝典')
    book_obj1.authors.add(1)
    
    book_obj1=Book.objects.get(title='桃花宝典')
    book_obj1.authors.add(1,4)
    
    • 1
    • 2
    • 3
    • 4
    • 5

     

    1.2 改

    一对多,一对一

    update()方法

    同样是两种方式:传入修改的字段,或者传入一个对象

    # 方式一:
    Book.objects.filter(title='三国志').update(publish_id=2)
    
    # 方式二:
    publish_obj = Publish.objects.filter(pk=2).first
    .objects.filter(title='三国志').update(publish=publish_obj)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    多对多

    set()方法

    该方法,括号内需要传入的是可迭代对象

    需要注意:在哪个表中创建的ManyToManyField对应的虚拟字段,那么就使用哪个表的add()方法

    方式一:根据对象添加

    # 1、先获取书籍对象
    book_obj1=Book.objects.get(title='葵花宝典')
    
    # 2、然后获取作者对象
    lili=Author.objects.get(name='lili')
    frank=Author.objects.get(name='frank')
    
    # 3、最后修改上述关系:
    book_obj1.authors.set([lili,frank])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    方式二:直接传入主键值

    book_obj1=Book.objects.get(title='菊花宝典')
    book_obj1.authors.set([2,1])
    
    • 1
    • 2

     

    1.3 删除

    一对多,一对一

    delete()方法

    Django 1.x 外键字段默认就是级联删除;2.x 以及以上的版本,需要自己指定 on_delete 字段

    Publish.objects.filter(pk=3).delete()
    # 出版社表删除了主键为 3 的,那么书籍表中出版社ID 为 3 的书籍也会被删除
    
    • 1
    • 2

    多对多

    remove()方法

    该方法可以删除一个或者多个

    方式一:根据对象删除

    # 1、先获取书籍对象
    book_obj1=Book.objects.get(title='葵花宝典')
    
    # 2、然后获取作者对象
    lili=Author.objects.get(name='lili')
    frank=Author.objects.get(name='frank')
    
    # 3、最后修改上述关系:
    book_obj1.authors.remove([lili,frank])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    方式二:直接传入主键值

    book_obj1=Book.objects.get(title='菊花宝典')
    book_obj1.authors.remove([2,1])
    
    • 1
    • 2

    clear()方法

    该方法用于清空

    book_obj1=Book.objects.get(title='菊花宝典')
    book_obj1.authors.clear()
    
    • 1
    • 2

     

    外键字段操作总结

    一对一关系,一对多关系 的操作都是一样的:找到外键字段所在的表,然后根据该表进行操作

    多对多关系的表的操作,需要先找到外键字段所在的表,然后再确定另外一张表中需要操作的字段,最后再根据外键字段所在的表进行操作;并且操作所使用的的方法是不同的


     

  • 相关阅读:
    软件测试学习笔记丨持续集成DevOps - Jenkins安装
    【js】-【DFS、BFS应用】-学习笔记
    Scala配置和Spark配置以及Scala一些函数的用法(附带词频统计实例)
    Software Engineering Patterns for Designing Machine Learning Systems
    golang将pcm格式音频转为mp3格式
    EKF之雅克比矩阵(一)
    12. 【containerd】snapshot服务解析
    ts 枚举类型原理及其应用详解
    DolphinScheduler 进阶(工作流传参)
    视频特效制作软件 After Effects 2024 mac中文版新增功能
  • 原文地址:https://blog.csdn.net/weixin_43988680/article/details/125450204