Django数据映射(一对一,一对多,多对多)

目录
  • 数据表关联关系映射
  • 一对一映射
    • 用法示例
  • 一对多映射
    • 用法示例
  • 多对多映射
    • 用法示例

数据表关联关系映射

常用的表关联方式有三种:

一对一映射
如: 一个身份证对应一个人

一对多映射
如: 一个班级可以有多个学生

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

一对一映射

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

语法

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

外键类字段选项

特殊字段参数【必须项】:

on_delete

  • models.CASCADE 级联删除。 Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。
  • models.PROTECT 抛出ProtectedError 以阻止被引用对象的删除;[等同于mysql默认的RESTRICT]
  • models.SET_NULL 设置ForeignKey null;需要指定null=True
  • models.SET_DEFAULT 将ForeignKey设置为其默认值;必须设置ForeignKey的默认值。
  • … 其它参请参考文档 https://docs.djangoproject.com/en/2.2/ref/models/fields/#foreignkey

其余常用的字段选项【非必须项】;如:

  • null
  • unique 等

用法示例

创建作家和作家妻子类

# file : xxxxxxxx/models.py
from django.db import models

class Author(models.Model):
    '''作家模型类'''
    name = models.CharField('作家', max_length=50)

class Wife(models.Model):
    '''作家妻子模型类'''
    name = models.CharField("妻子", max_length=50)
    author = models.OneToOneField(Author, on_delete=models.CASCADE)  # 增加一对一属性 

创建一对一的数据记录

from .models import *
author1 = Author.objects.create(name='王老师')
wife1 = Wife.objects.create(name='王夫人', author=author1)  # 关联王老师
author2 = Author.objects.create(name='小泽老师')  # 一对一可以没有数据对应的数据

数据查询

正向查询

直接通过关联属性查询即可

# 通过 wife 找 author
from .models import Wife
wife = Wife.objects.get(name='王夫人')
print(wife.name, '的老公是', wife.author.name)

反向查询

  • 通过反向关联属性查询
  • 反向关联属性为实例对象.引用类名(小写),如作家的反向引用为作家对象.wife
  • 当反向引用不存在时,则会触发异常
# 通过 author.wife 关联属性 找 wife,如果没有对应的wife则触发异常
author1 = Author.objects.get(name='王老师')
print(author1.name, '的妻子是', author1.wife.name)
author2 = Author.objects.get(name='小泽老师')
try:
    print(author2.name, '的妻子是', author2.wife.name)
except:
    print(author2.name, '还没有妻子')

一对多映射

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

语法

当一个A类对象可以关联多个B类对象时

class A(model.Model):
    ...

class B(model.Model):
    属性 = models.ForeignKey("一"的模型类, on_delete=xx)

用法示例

有二个出版社对应五本书的情况.

清华大学出版社 有书

  • C++
  • Java
  • Python

北京大学出版社 有书

  • 西游记
  • 水浒

创建模型类

# file: otm/models.py
from django.db import models

class Publisher(models.Model):
    '''出版社【一】'''
    name = models.CharField('名称', max_length=50, unique=True)

class Book(models.Model):
    '''书【多】'''
    title = models.CharField('书名', max_length=50)
    publisher = ForeignKey(Publisher, on_delete=models.CASCADE)

创建数据

#先创建 '一' ,再创建 '多'
from .models import *
pub1 = Publisher.objects.create(name='清华大学出版社')
Book.objects.create(title='C++', publisher=pub1)
Book.objects.create(title='Java', publisher_id=1)

#高级创建 - 利用 反向属性
pub2 = Publisher.objects.create(name='北京大学出版社')
pub2.book_set.create(title='西游记')

数据查询

通过 Book 查询 Publisher【正向】

通过 publisher 属性查询即可
​​​​​​​book.publisher

abook = Book.objects.get(id=1)
print(abook.title, '的出版社是:', abook.publisher.name)

通过 Publisher 查询 对应的所有的 Book 【反向】

Django会在Publisher中增加一个属性来表示对对应的Book们的查询引用
属性:book_set  等价于 objects

# 通过出版社查询对应的书
pub1 = Publisher.objects.get(name='清华大学出版社')
books = pub1.book_set.all()  # 通过book_set 获取pub1对应的多个Book数据对象
#books = Book.objects.filter(publisher=pub1)  # 也可以采用此方式获取
print("清华大学出版社的书有:")
for book in books:
   print(book.title)

多对多映射

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

在关联的两个类中的任意一个类中,增加:

属性 = models.ManyToManyField(MyModel)

用法示例

  • 一个作者可以出版多本图书
  • 一本图书可以被多名作者同时编写
class Author(models.Model):
    ...

class Book(models.Model):
    ...
    authors = models.ManyToManyField(Author)

创建模型类

class Author(models.Model):
    '''作家模型类'''
    name = models.CharField('作家', max_length=50)
    def __str__(self):
        return self.name

class Book(models.Model):
    '''书模型类'''
    title = models.CharField('书名', max_length=50)
    authors = models.ManyToManyField(Author)
    def __str__(self):
           return self.title

创建数据

方案1 先创建 author 再关联 book
    author1 = Author.objects.create(name='吕老师')
    author2 = Author.objects.create(name='王老师')
    # 吕老师和王老师同时写了一本Python
    book11 = author1.book_set.create(title="Python")
    author2.book_set.add(book11) 

方案2 先创建 book 再关联 author
    book = Book.objects.create(title='python1')
    #郭小闹和吕老师都参与了 python1 的 创作
    author3 = book.authors.create(name='guoxiaonao')
    book.authors.add(author1)

数据查询

通过 Book 查询对应的所有的 Author【正向】

book.authors.all() -> 获取 book 对应的所有的author的信息
book.authors.filter(age__gt=80) -> 获取book对应的作者中年龄大于80岁的作者的信息

通过 Author 查询对应的所有的Book【反向】

Django会生成一个反向属性 book_set 用于表示对对应的book的查询对象相关操作

author.book_set.all()
author.book_set.filter()

到此这篇关于Django数据映射(一对一,一对多,多对多)的文章就介绍到这了,更多相关Django 数据映射内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2022-08-10

django中url映射规则和服务端响应顺序的实现

 1.django搜索路径 使用 import 语句时,Python 所查找的系统目录清单. 查看方式: import sys print sys.path 通常无需关心 Python 搜索路径的设置,Python 和 Django 会在后台自动帮你处理好. 2.url匹配模式 基本结构: '^需要匹配的url字符串$' PS:实际上最终完整的url串是http://根路径:端口号/需要匹配的url字符串 系统自动添加的部分'http://根路径:端口号/' eg:url匹配模式:'^lates

Django框架视图层URL映射与反向解析实例分析

本文实例讲述了Django框架视图层URL映射与反向解析.分享给大家供大家参考,具体如下: Django视图层主要工作就是衔接HTTP请求.python程序.HTML模板. URL分发(URL dispatcher)映射配置可以被看作Django项目的入口配置(项目下的urls.py以及应用的下的urls.py,include将两者联系起来在项目下的urls.py),通过URLdispatcher可以指定用户的每一个访问的后台的python处理函数是什么. 1.普通url映射 每一个Django

Django如何将URL映射到视图

前言 URLconf 就像是 Django 所支撑网站的目录.它的本质是 URL 模式以及要为该 URL 模式调用的视图函数之间的映射表.你就是以这种方式告诉 Django,对于这个 URL 调用这段代码,对于那个 URL 调用那段代码.但必须记住的是视图函数必须位于 Python 搜索路径之中. Python 搜索路径 Python 搜索路径 就是使用 import 语句时, Python 所查找的系统目录清单. 举例来说,假定你将 Python 路径设置为['','/usr/lib/pyth

对Django项目中的ORM映射与模糊查询的使用详解

ORM映射 什么是ORM映射?在笔者认为就是对SQL语句的封装,所写语句与SQL对应语句含义相同,使开发更加简单方便,不过也是存在弊端的,使程序运行效率下降.例如: UserInfo.objects.get(id=2) 等于 select * from user_userinfo where id=2 修改管理器(models.py) 导入新的包:from django.db import models 进行模糊查询 开始进行查找前我们先来认识filter()方法. 这是一个过滤器方法用于过滤掉

Django 对象关系映射(ORM)源码详解

前言 从前面已经知道, 一个 request 的到来和一个对应 response 的返回的流程, 数据处理和数据库离不开. 我们也经常在 views.py 的函数定义中与数据库打交道. django ORM 源代码组织结构 对于数据库, django 有自己的一套 ORM(对象关系映射), 或许其他的框架可以随意更换 ORM, 但 django 不建议这么做. 因为 django 内置有很多的 model, 这些 model 无疑是用 django 内置 ORM 实现的, 如果更换后, 内置的

Android实现屏幕锁定源码详解

最近有朋友问屏幕锁定的问题,自己也在学习,网上找了下也没太详细的例子,看的资料书上也没有有关屏幕锁定程序的介绍,下个小决心,自己照着官方文档学习下,现在做好了,废话不多说,先发下截图,看下效果,需要注意的地方会加注释,有问题的朋友可以直接留言,我们共同学习交流,共同提高进步!直接看效果图: 一:未设置密码时进入系统设置的效果图如下: 二:设置密码方式预览: 三:密码解密效果图 四:九宫格解密时的效果图 下面来简单的看下源码吧,此处讲下,这个小DEMO也是临时学习下的,有讲的不明白的地方请朋友直接

Django 响应数据response的返回源码详解

响应数据的返回 在 WSGIHandler.__call__(self, environ, start_response) 方法调用了 WSGIHandler.get_response() 方法, 由此得到响应数据对象 response. 如今所要做的, 便是将其返回给客户端. 在 Django 源码小剖: 初探 WSGI中, 简要的概括了请求到来时 django 自带服务器的执行关系, 摘抄如下: make_server() 中 WSGIServer 类已经作为服务器类, 负责接收请求, 调用

Android context源码详解及深入分析

Android context详解 前言: Context都没弄明白,还怎么做Android开发? Activity mActivity =new Activity() 作为Android开发者,不知道你有没有思考过这个问题,Activity可以new吗?Android的应用程序开发采用Java语言,Activity本质上也是一个对象,那上面的写法有什么问题呢?估计很多人说不清道不明.Android程序不像Java程序一样,随便创建一个类,写个main()方法就能运行,Android应用模型是基

php-msf源码详解

我们来看分享下具体源码:php-msf: https://github.com/pinguo/php-msf 源码解读也做了一段时间了, 总结一下自己的心得: 抓住 生命周期, 让代码在你脑海中 跑起来 分析架构, 关键字 分层 边界 隔离 一个好的框架, 弄清楚 生命周期 和 架构, 基本就已经到了 熟悉 的状态了, 之后是填充细节和编码熟练了 这里再介绍几个次重要的心得: 弄明白这个工具擅长干什么, 适合干什么. 这个信息也非常容易获取到, 工具的文档通常都会显眼标注出来, 可以通过这些 功

源码详解Android中View.post()用法

emmm,大伙都知道,子线程是不能进行 UI 操作的,或者很多场景下,一些操作需要延迟执行,这些都可以通过 Handler 来解决.但说实话,实在是太懒了,总感觉写 Handler 太麻烦了,一不小心又很容易写出内存泄漏的代码来,所以为了偷懒,我就经常用 View.post() or View.postDelay() 来代替 Handler 使用. 但用多了,总有点心虚,View.post() 会不会有什么隐藏的问题?所以趁有点空余时间,这段时间就来梳理一下,View.post() 原理到底是什

微信 小程序前端源码详解及实例分析

微信小程序前端源码逻辑和工作流 看完微信小程序的前端代码真的让我热血沸腾啊,代码逻辑和设计一目了然,没有多余的东西,真的是大道至简. 废话不多说,直接分析前端代码.个人观点,难免有疏漏,仅供参考. 文件基本结构: 先看入口app.js,app(obj)注册一个小程序.接受一个 object 参数,其指定小程序的生命周期函数等.其他文件可以通过全局方法getApp()获取app实例,进而直接调用它的属性或方法,例如(getApp().globalData) //app.js App({ onLau

JS小游戏之宇宙战机源码详解

本文实例讲述了JS小游戏的宇宙战机源码,分享给大家供大家参考.具体介绍如下: 一.游戏介绍: 这是一款飞行射击游戏,纵向,共六关. 二.游戏需求: 1.战机可发射子弹,子弹可通过获取道具升级. 2.战机可放bomb,可获取道具增加数量. 3.战机可蓄力攻击. 4.道具有三种,分别是升级子弹,增加bomb数量,增加战机数量. 5.每关音乐不同. 6.战机被击落后再进入战场,有保护状态. 7.敌机AI设计. 游戏运行如下图所示: 完整实例代码点击此处本站下载. 三.Javascript源码部分: /

Java集合Stack源码详解

概要 学完Vector了之后,接下来我们开始学习Stack.Stack很简单,它继承于Vector.学习方式还是和之前一样,先对Stack有个整体认识,然后再学习它的源码:最后再通过实例来学会使用它. 第1部分 Stack介绍 Stack简介 Stack是栈.它的特性是:先进后出(FILO, First In Last Out). java工具包中的Stack是继承于Vector(矢量队列)的,由于Vector是通过数组实现的,这就意味着,Stack也是通过数组实现的,而非链表.当然,我们也可以

ReentrantLock源码详解--公平锁、非公平锁

问题 (1)重入锁是什么? (2)ReentrantLock如何实现重入锁? (3)ReentrantLock为什么默认是非公平模式? (4)ReentrantLock除了可重入还有哪些特性? 简介 Reentrant = Re + entrant,Re是重复.又.再的意思,entrant是enter的名词或者形容词形式,翻译为进入者或者可进入的,所以Reentrant翻译为可重复进入的.可再次进入的,因此ReentrantLock翻译为重入锁或者再入锁. 重入锁,是指一个线程获取锁之后再尝试获