【Django】ORM关系映射

关系映射

在关系型数据库中,通常不会把所有数据都放在同一张表中,不易于扩展,常见的关系映射有:

  1. 一对一映射,如一个身份证对应一个人。

  2. 一对多映射,如一个班级可以有多个学生。

  3. 多对多映射,如一个学生可以报多个课程,一个课程可以有多个学生学习。

1 一对一映射

1.1 一对一映射定义

  • 一对一是表示现实事物间存在的一对一的对应关系。如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的身份证号等。

1.2 一对一映射创建模型

  • 语法:OneToOneField(类名,on_delete=xxx),on_delete:级联删除。

    class A(model.Model):...
    class B(model.Model):属性 = models.OneToOneField(A, on_delete=xxx)

  • 特殊字段选项【必须】,on_delete,级联删除。

Django中的一对一映射

  1. models.CASCADE 级联删除,Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForegnKey的对象。

  2. models.PROTECT 抛出ProtectedError 以组织被引用对象的删除,等同于 mysql 默认的RESTRICT。

  3. SET_NULL 设置 ForeignKey null,需要指定 null=True;

  4. SET_DEFAULT 将 ForeignKey 设置为其默认值,必须设置ForeignKey默认值。

代码示例:

from django.db import models
​
# 关系说明:一个人只有一个身份证号码,一个身份证号码对应一个人
# Create your models here.
class Person(models.Model):"""个人类"""name = models.CharField("姓名", max_length=11, default='', null=False)age = models.IntegerField("年龄", default=1)home = models.CharField("住址", max_length=256, default='')
​def __str__(self):return "%s_%s_%s" % (self.name, self.age, self.email)
​
class IdCard(models.Model):"""身份证件"""idCardNUmber = models.CharField("身份证号码", max_length=32, null=False)person = models.OneToOneField(Person, on_delete=models.CASCADE) # 一对一属性

1.3 一对一映射创建数据

# 无外键的模型类[Person]:
person = Person.objects.create(name='南歌', age=20, home='陕西省延安市')
# 有外键的模型类[IdCard]
idcard = IdCard.objects.create(idCardNUmber='xxxx', person=person)
# 也即关联个人的主键值
idcard = IdCard.objects.create(idCardNUmber='xxxx', person_id=person_id)

直接关联外键对应的对象。

数据库查看。

关联外键对应对象的主键值。

数据库查看。

1.4 一对一映射查询数据

  1. 正向查询:直接通过关联的外键属性查询,则称为正向查询。

    # 通过IdCard查找Person
    from oto.models import *
    idCard = IdCard.objects.get(idCardNUmber='xxxx')
    ​
    print("身份证号:{idCardNUmber}的人姓名为:{name}".format(idCardNUmber=idCard.idCardNUmber, name=idCard.person.name))
  2. 反向查询:没有外键属性的一方,可以调用反向属性查询到关联的另一方。

    注:

    • 反向关联属性为 实例对象.引用类名(小写),如个人的反向引用为 个人对象.idcard

    • 当反向引用不存在时,则会触发异常。

    # 通过IdCard查找Person
    from oto.models import *
    ​
    person = Person.objects.get(name='南歌')
    person.idcard.idCardNUmber

    反向属性不存在时,触发异常。

2 一对多映射

2.1 一对多映射定义

  • 一对多是表现现实事物间存在的一对多的对应关系。如:一个学校有多个班级,一个班级有多个学生,一本图书只能属于一个出版社,一个出版社允许出版多本图书。

  • 一对多需要明确出具体角色,在多表上设置外键。

2.2 一对多映射创建模型

  • 语法

    # 当一个A类对象可以关联多个B类对象时
    class A(models.Model):...class B(models.Model):属性  = models.Foreignkey("一"的模型类, on_delete=xx)
    # Fortignkey 必须指定 on_delete模式

代码示例:

from django.db import models
​
# Create your models here.
# 关系说明:一个出版社可以有多本图书,一个图书只能对应一个出版社
class Press(models.Model):"""出版社"""name = models.CharField("名称", max_length=128, unique=True)
​
​
class Book(models.Model):"""图书"""name = models.CharField("书名", max_length=128)press = models.ForeignKey(Press, on_delete=models.CASCADE)

2.3 一对多映射创建数据

# 先创建一,再创建多
from otm.models import *
press = Press.objects.create(name="东北大学出版社")
​
Book.objects.create(name="C++教程", press=press)
Book.objects.create(name="Python教程", press_id=press_id)

2.4 一对多映射查询数据

  1. 正向查询:直接通过关联的外键属性查询,则称为正向查询。

    # 通过Book查找Press
    from otm.models import *
    book = Book.objects.get(name='Python教程')
    ​
    print("{book}的出版社是{name}".format(book=book.name, name=book.press.name))
  2. 反向查询:没有外键属性的一方,可以调用反向属性查询到关联的另一方。

    # 通过 Press 查找 Book
    from otm.models import *
    press = Press.objects.filter(name='东北大学出版社')
    books = press.book_set.all()

3 多对多映射

3.1 多对多定义

  • 多对多表达对象之间多对多复杂关系,如:每个人都有不同的学校(小学,初中,高中,...),每个学校都有不同的学生...

  • Mysql中创建多对多需要依赖第三张表来实现。

  • Django中无需手动创建第三张表,Django自动完成。

3.2 多对多映射创建模型

  • 语法:在关联的两个类中的任意一个类中增加:

    属性 = models.ManyToManyField(MyModel)

  • 代码示例:

    # 关系说明:一个作者可以出版多本图书,一本图书可以被多名坐着同时编写
    ​
    from django.db import models
    ​
    # Create your models here.
    class Author(models.Model):name = models.CharField("作者", max_length=128)
    ​
    ​
    class Book(models.Model):name = models.CharField("书名", max_length=128)authors = models.ManyToManyField(Author)

3.3 多对多映射创建数据

# 方案一:先创建author再关联book
author1 = Author.objects.create(name="南歌")
author2 = Author.objects.create(name="EuanSu")
## 南歌和EuanSu同时写了一本《Django教程》
book = author1.book_set.create(name="Django教程")
author2.book_set.add(book)
​
# 方案二:先创建book再关联author
book = Book.objects.create(name="Python教程")
## 南歌和EuanSu都参与了《Python教程》的编写
author = book.authors.create(name="南歌")
book.authors.add(author)

3.4 多对多映射查询数据

  1. 正向查询:直接通过关联的外键属性查询,则称为正向查询。

    # 通过Book查询对应所有的 Author,此时多对多属性等价于objects
    ## 获取 book 对应的所有author信息
    book.authors.all() 
    ## 获取book对应作者中名字为南歌的author
    book.authors.filter(name="南歌")
  2. 反向查询:没有外键属性的一方,可以调用反向属性查询到关联的另一方。

    # 通过Author查询对应所有的book,利用反向属性book_set
    author.book_set.all()
    author.book_set.filter(name="Django教程")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/458889.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯嵌入式学习记录——点亮第一个LED(含软件的使用)

目录 一、蓝桥杯概述 二、软件的使用 三、点亮LED 一、蓝桥杯概述 蓝桥杯是一个编程大赛、商赛,获奖率高达60%(省赛中一等奖10%、二等奖20%、三等奖30%),但这并不影响它的含金量,多所高校将它列为A类赛事并实行保研…

基于SpringBoot和PostGIS的震中影响范围可视化实践

目录 前言 一、基础数据 1、地震基础信息 2、全国行政村 二、Java后台服务设计 1、实体类设计 2、Mapper类设计 3、控制器设计 三、前端展示 1、初始化图例 2、震中位置及影响范围标记 3、行政村点查询及标记 总结 前言 地震等自然灾害目前还是依然不能进行准确的预…

机器人运动学林沛群——旋转矩阵

旋转矩阵 基本概念 三个主轴,可以看作是三个向量,为b在a的表达,以a为基准 旋转矩阵 B相对于A的姿态: B A R [ A X B ^ A Y B ^ A Z B ^ ] [ X ^ B ⋅ X ^ A Y ^ B ⋅ X ^ A Z ^ B ⋅ X ^ A X ^ B ⋅ Y ^ A Y ^ B ⋅ Y ^ A Z …

2024年2月8日 十二生肖 今日运势

小运播报:2024年2月8日,星期四,农历腊月廿九 (甲辰年丙寅月壬寅日),法定工作日。 红榜生肖:马、猪、狗 需要注意:龙、蛇、猴 喜神方位:正南方 财神方位:正…

外汇天眼:香港监管机构禁止Nerico Brothers前持牌代表五年

香港证券及期货事务监察委员会(SFC)已经禁止Nerico Brothers Limited的前持牌代表林清超先生和黄肇峰先生重新进入行业,为期五年。禁令将从2024年2月6日持续至2029年2月5日,此举是因为林和黄分别因行贿罪被判有罪。 林和黄于2022年…

3.2-媒资管理之MinIo分布式文件系统+上传图片

媒资管理 3 分布式文件系统 3.1 什么是分布式文件系统 要理解分布式文件系统首先了解什么是文件系统。 查阅百度百科: 文件系统是负责管理和存储文件的系统软件,操作系统通过文件系统提供的接口去存取文件,用户通过操作系统访问磁盘上的文…

机器学习系列——(七)简单分类算法

机器学习是目前人工智能领域最热门的分支之一,其中朴素贝叶斯分类算法是一种常用的分类算法。本文将详细介绍朴素贝叶斯分类算法的原理、应用以及优缺点。 一、原理 朴素贝叶斯分类算法是一种基于贝叶斯定理的分类算法。在分类问题中,我们需要根据给定的…

【JavaEE Spring】Spring 原理

Spring 原理 1. Bean的作⽤域1.1 概念1.2 Bean的作⽤域 2. Bean的⽣命周期 1. Bean的作⽤域 1.1 概念 在Spring IoC&DI阶段, 我们学习了Spring是如何帮助我们管理对象的. 通过 Controller , Service , Repository , Component , Configuration ,Bean 来声明Bean对象。通…

【Linux开发工具】gcc/g++的使用

📙 作者简介 :RO-BERRY 📗 学习方向:致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持 目录 1.前言2.gcc/g使用方…

手把手教你激活FL Studio 21.2.2.3914中文破解版2024年图文激活教程以及如何设置中文language

FL Studio 21.2.2.3914软件简介 fl studio 21.2.2.3914中文破解版作为一款极具创意性的音乐软件工作站软件,FL Studio已经成为了许多音乐制作人和音乐爱好者的首选。最新的FL Studio 21.2.2.3914中文破解版的发布,无疑将会引起更多人的关注。 ​ FL St…

《Java程序设计》实验报告(一)之Java语言基础

实验内容及步骤: 编写”hello world”应用程序。(1)代码: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello world!"); } } (2)运行…

【Langchain+Streamlit】旅游聊天机器人

【LangchainStreamlit】打造一个旅游问答AI-CSDN博客 项目线上地址,无需openai秘钥可直接体验:http://101.33.225.241:8502/ github地址:GitHub - jerry1900/langchain_chatbot: langchainstreamlit打造的一个有memory的旅游聊天机器人&…