• ORM多表外键字段的操作


    目录

    数据准备

    多表操作--外键字段

    1.增

    多对一

    一对一

    多对多

    一对多., 一对一

    多对多

    删除

    一对多,一对一

    多对多

    remove()方法

    clear() 方法

    外键字段操作总结


    数据准备

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

    按照上图所示.由于foreignkey的关系, 我们需要实现往 app01_publish 与app01_authordetail里插入记录

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

    多表操作--外键字段

    1.增

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

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

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

    多对一

    1. # 线通过魔心Publish从出版社表app01_publish查出北京出版社
    2. publish_obj = Publish.objects.filter(name='北京出版社').first()

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

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

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

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

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

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

    一对一

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

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

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

    多对多

    add()方法

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

    方式一: 根据对象添加

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

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

    方式二: 直接传入主键值

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

    一对多., 一对一

    update()方法

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

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

    多对多

    set()方法

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

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

    方式一: 根据对象添加

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

    方式二: 直接传入主键值

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

    删除

    一对多,一对一

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

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

    多对多

    remove()方法

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

    方式一: 根据对象删除

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

    方式二: 直接传入主键值

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

    clear() 方法

    该方法用于清空

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

    外键字段操作总结

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

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

  • 相关阅读:
    【NOIP2018模拟10.30】Idioms 题解
    c盘分小了如何扩大c盘,重新分区扩大c盘
    PDF格式分析(六十八)——注释(批注)概要
    Nacos注册中心有几种调用方式?
    初识ElasticSearch
    推荐10个AI人工智能技术网站(一键收藏,应有尽有)
    检索增强微调(RAFT)---使语言模型适应特定领域的 RAG
    常用工具记录
    Docker容器内用户与宿主机用户同名不同ID的问题
    第6篇 vue的打包工具webpack
  • 原文地址:https://blog.csdn.net/weixin_67531112/article/details/126715517