最新要闻
- 4K 3D 高帧率重制!《泰坦尼克号》重映预售开启:4月3日上映
- 热推荐:沪一男子多次在五星级酒店开房,记录和发票被“神秘女”轻松拿走?细思极恐...
- 天天滚动:外卖小哥专属!美团发布头盔新专利:手不脱把接电话
- 【世界报资讯】库克现身北京三里屯正面“面对”小米!网友手持小米13 Pro合影太吸睛
- 当前速看:马斯克要建自己的乌托邦城市:美国当地居民这下不淡定了
- 每日短讯:正式定档4月26日!米哈游大作《崩坏:星穹铁道》公测官宣
- 环球报道:《暗黑破坏神4》新手入门图文攻略:游戏系统介绍与开荒指南
- 天天日报丨男孩名字含“坤”被嘲笑抑郁自残 被起绰号“鸡哥”:网友吐槽太过分
- 环球要闻:监控拍到浙江一车辆撞倒行人后又倒回碾压!官方通报来了
- 全球快资讯丨金价一路狂飙 有人8斤黄金变现174万:国内中老年狂买 还有人已赚32万元
- 世界热头条丨暴雪计划进行压力测试:《暗黑破坏神4》公测版排队依旧
- 以志愿服务赋能基层治理,金山卫镇这样做
- 每日看点!优化不够DLSS来凑 iGame RTX 4080显卡实战《卧龙》:4K轻松百帧
- 环球热点!男子驾车疯狂违章 上传视频炫耀自曝!后续舒适
- 169元 红魔散热器4磁吸版上市:20W满血功率、可控RGB灯效
- 环球热讯:苹果CEO库克现身北京三里屯零售店!众多粉丝合影 有人用小米13自拍
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
Django笔记七之ManyToMany和OneToOne介绍
ManyToMany 是一种多对多的关系,在用途和使用方法上和外键 ForeignKey 类似。
【资料图】
以下是本篇笔记的目录:
- ManyToMany 的介绍
- through 参数
- through_fields 参数
- ManyToMany关系数据的增删改查
- OneToOne介绍
1、ManyToMany 的介绍
假设有两个 model,Person 和 Group,这两个model之间是多对多的关系。那么我们可以如下创建其关系:
# blog/models.pyclass Person(models.Model):name = models.CharField(max_length=64)class Group(models.Model):name = models.CharField(max_length=64)members = models.ManyToManyField(Person)
通过上述代码我们就创建了有多对多关系两个model,当我们执行 migrate 操作之后(可以先不执行,后续还会对其有所更改),系统除了会创建 Person 和 Group 这两个表之外,还会创建一个表。
表名为 blog_group_members,因为是放在 Blog 这个 application 下面,所以,表名的前缀是 blog,然后加上 model 名的小写为 group,加上字段名称 members。
这张第三方表会有两个字段,person_id 和 group_id,将这两个 model 关联起来。
通过往这张第三方表写入 person_id 和 group_id的数据,我们就将这两个 model 关联了起来。
而获取他们对应的关系的记录和 ForeignKey 的关系类似:
根据 Person 数据查询关联的 Group 数据:
person = Person.objects.get(id=1)group_list = person.group_set.all() # 使用 Group 的小写加 _set
根据 Group 数据查询关联的 Person 数据,这个查询方法略微不同,用到的是 Group 定义的 members 字段:
group = Group.objects.get(id=1)person = group.members.all() # 根据条件来搜索 person 也是可以的person = group.members.filter(name="hunter")
2、through参数
上面 ManyToMany 的定义中,我们没有加任何参数,所以自动创建的表名是默认的,字段也只是两个 model 的主键id。
而如果我们有一些额外的需求,比如说,为 Person 和 Group 添加关联关系时,需要加上关联时间,或者想自己指定表名或 model 名的时候,我们可以通过 through 属性来指定 model 的名称,然后为其添加我们需要的字段。
比如我们想为 Person 和 Group 创建一个多对多的关系,指定model 名为 Membership,且额外添加字段,比如添加时间,可以通过 through 参数来指定:
class Person(models.Model): name = models.CharField(max_length=50)class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField( Person, through="Membership", )class Membership(models.Model): person = models.ForeignKey(Person, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE) date_joined = models.DateField()
3、through_fileds参数
在我们上面创建的 Membership model 中,我们对应的多对多的字段分别是 person 和 group,所以系统可以自动找到对应的多对多的字段。
如果在第三方表,也就是 Membership 中,有多个相同的 Person 或者 Group 的字段,就需要通过 through_fields 参数来指定多对多的字段:
class Person(models.Model): name = models.CharField(max_length=50)class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField( Person, through="Membership", through_fields=("group", "person"), )class Membership(models.Model): group = models.ForeignKey(Group, on_delete=models.CASCADE) person = models.ForeignKey(Person, on_delete=models.CASCADE) inviter = models.ForeignKey( Person, on_delete=models.CASCADE, related_name="membership_invites", ) invite_reason = models.CharField(max_length=64)
4、ManyToMany关系数据的增删改查
接下来,我们定下最终的几个 model 内容如下,用于演示 ManyToMany 的增删改查的操作:
class Person(models.Model): name = models.CharField(max_length=50)class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField( Person, through="Membership", )class Membership(models.Model): person = models.ForeignKey(Person, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE) date_joined = models.DateField() invite_reason = models.CharField(max_length=64)
现在我们有 Person 和 Group 两个model,还有两个 model 之间的关系表 Membership,如果我们要创建一个对应的关系,则需要创建一个 Membership 实例。
创建
首先创建 Person 和 Group 的记录:
from blog.models import Person, Group, Membershiphunter = Person.objects.create(name="hunter")group_1 = Group.objects.create(name="group_1")
创建多对多记录:
m1 = Membership.objects.create(person=hunter, group=group_1, date_joined="2022-01-01", invite_reason="xxx")
根据单个 Person 记录获取所有相关 Group 记录,使用方法同外键搜索方法:
groups = hunter.group_set.all()
根据单个 Group 记录获取所有相关 Person 记录,根据多对多字段来搜索:
persons = group_1.members.all()
根据 Membership 关系记录获取 Person 和 Group 记录,可以直接用外键的的方式使用:
m1.personm1.group
根据 Group 使用 add 添加一条多对多记录:
paul = Person.objects.create(name="pual")group_1.members.add(paul, through_defaults={"date_joined": "2022-01-01"})
其中,through_defaults 参数为字典,内容为多对多关系表的额外添加的字段。
根据 Group 使用 create 创建一条多对多记录:
如果没有相应的 Person 记录,可以根据 Group 来直接创建
group_1.members.create(name="mary", through_defaults={"date_joined": "2022-01-01"})
根据 Group 使用 set 刷新多对多记录:
使用 set 方法来设置多对多的关系:
jack = Person.objects.create(name="jack")lucy = Person.objects.create(name="lucy")group_1.members.set([jack, lucy], through_defaults={"date_joined": "2022-01-01"})
需要注意的是,使用 set() 方法加上关联之后,这个 Group 实例之前设置的关联数据都会被清除。
也就是说,set() 里设置的关联数据就是最终所有的关联数据。
根据 Group 使用 remove 删除一条多对多记录:
在上面 我们使用了 set() 方法设置了两条关联数据,jack 和 lucy,现在我们想要把 jack——group_1 这条关系删除,可使用 remove() 方法:
group_1.members.remove(jack)
使用 clear 清除某个 Group 实例上所有关系:
group_1.members.clear()
多对多的搜索:
根据 Person 的条件搜索 Group 的数据:
比如搜索 Person 的 name 字段为 "hunter" 的 Group 数据
Group.objects.filter(members__name="hunter")
根据 Group 的条件搜索 Person 的数据:
比如搜索 Group 的 name 字段为 "group_1" 的Person关联数据:
Person.objects.filter(group__name="group_1")
如果要搜索额外的关联字段:
Person.objects.filter(group__name="group_1", membership__date_joined="2022-01-01")
5、OneToOne 介绍
不同于 多对一和多对多的关系,OneToOne 是一对一的关系,也就是说 一条数据仅能被另一条数据关联。
下面是两个 OneToOne 对应的 model:
class Place(models.Model): name = models.CharField(max_length=50) address = models.CharField(max_length=80) def __str__(self): return "%s the place" % self.nameclass Restaurant(models.Model): place = models.OneToOneField(Place, on_delete=models.CASCADE, default=None, related_name="place_restaurant", null=True)
接下来创建两条数据:
r_1 = Restaurant.objects.create()p_1 = Place.objects.create(name="beijing", address="beijing")
根据 Restaurant 获取 Place 数据,直接根据字段获取数据:
r_1.place
如果根据 Place 获取 Restaurant 数据,因为是 OneToOne 的关系,所以可以直接获取:
上面的 model 中我们定义了 related_name,所以是:
p_1.place_restaurant
如果没有定义 related_name 和 related_query_name 那么就是 model 的小写:
p_1.restaurant
但是从 Place 到 Restaurant 获取数据,如果没有这种 OneToOne 的对应,比如我们上面直接创建的 p_1,使用这种方式获取关联数据就会报错,因为没有这种 OneToOne 的数据。
那么这个时候我们可以先判断是否有对应的这种 OneToOne 的数据:
hasattr(p_1, "place_restaurant") # 返回的是布尔型数据 # 或者 getattr(p_1, "place_restaurant", None)
以上就是这篇笔记全部内容,接下来将要介绍 model 里的 Meta 的用法。
本文首发于本人微信公众号:Django笔记。
原文链接:Django笔记七之ManyToMany和OneToOne介绍
如果想获取更多相关文章,可扫码关注阅读:
关键词:
-
天天新消息丨Midjourney AI绘画使用指南
上图有Midjourney生成,提示语为:24-year-oldChinesewomanwithlonghairandaTeddMidjourney是一款基于Prompt设计和CL
来源: -
Django笔记七之ManyToMany和OneToOne介绍
ManyToMany是一种多对多的关系,在用途和使用方法上和外键ForeignKey类似。以下是本篇笔记的目录:ManyT...
来源: 天天新消息丨Midjourney AI绘画使用指南
Django笔记七之ManyToMany和OneToOne介绍
4K 3D 高帧率重制!《泰坦尼克号》重映预售开启:4月3日上映
热推荐:沪一男子多次在五星级酒店开房,记录和发票被“神秘女”轻松拿走?细思极恐...
【金融街发布】人民银行:2月发行各类债券54724.3亿元
债市日报:3月24日
天天滚动:外卖小哥专属!美团发布头盔新专利:手不脱把接电话
【世界报资讯】库克现身北京三里屯正面“面对”小米!网友手持小米13 Pro合影太吸睛
当前速看:马斯克要建自己的乌托邦城市:美国当地居民这下不淡定了
每日短讯:正式定档4月26日!米哈游大作《崩坏:星穹铁道》公测官宣
快消息!PaddleOCR之高性能Go语言实现OCR识别
环球报道:《暗黑破坏神4》新手入门图文攻略:游戏系统介绍与开荒指南
天天日报丨男孩名字含“坤”被嘲笑抑郁自残 被起绰号“鸡哥”:网友吐槽太过分
环球要闻:监控拍到浙江一车辆撞倒行人后又倒回碾压!官方通报来了
全球快资讯丨金价一路狂飙 有人8斤黄金变现174万:国内中老年狂买 还有人已赚32万元
世界热头条丨暴雪计划进行压力测试:《暗黑破坏神4》公测版排队依旧
以志愿服务赋能基层治理,金山卫镇这样做
9个都要了解的单行Python代码
每日看点!优化不够DLSS来凑 iGame RTX 4080显卡实战《卧龙》:4K轻松百帧
环球热点!男子驾车疯狂违章 上传视频炫耀自曝!后续舒适
169元 红魔散热器4磁吸版上市:20W满血功率、可控RGB灯效
环球热讯:苹果CEO库克现身北京三里屯零售店!众多粉丝合影 有人用小米13自拍
上海嘉定新城发展完成5亿元中票发行 利率3.20%
环球速讯:Leetcode Practice -- 字符串
第133篇:事件处理与常用事件
每日简讯:PLG SaaS 产品 Figma 商业模式拆解
1.爬虫的简介
世界时讯:python超时处理方法eventlet的eventlet.Timeout
全球资讯:【新华解读】REITs推出支持消费重要举措 消费基础设施可发行REITs
环球通讯!【财经分析】瑞信债务减记外溢影响可控 欧洲其他大型银行信用状况未受波及
【金融街发布】证券公司App“一键打新”功能将迎三大变化
每日热议!电池连续6年世界第一 宁德时代表态不会去造车
环球精选!95后设计师辞职当动物饲养员:上班以后非常开心
小金刚品质 Note 12 Turbo首发福利:免费送碎屏险
世界今头条!PC真的没落了!我国网民使用手机上网比例达99.8%:占比遥遥领先
每日关注!2023年国剧最高分!剧版《三体》豆瓣涨至8.7分:超36万人评价
焦点报道:windows安装redis及配置教程
世界微速讯:记一次若依后台管理系统渗透
焦点!记录--用three.js渲染真实的下雨效果
傲软录屏工具使用教程(附工具亲测有效!!!)
天天视点!国际货币基金组织敦促黎巴嫩加快改革以启动一揽子救助计划
全球简讯:论文阅读笔记(五):Hire-MLP Vision MLP via Hierarchical Rearrangement
【焦点热闻】73.迭代器
环球观察:[vue] 脚手架笔记
世界动态:别让疲劳成为你的最后一程路:如何避免驾驶疲劳?丨曼孚科技
前沿资讯!L2-040 哲哲打游戏
每日快看:【新华500】新华500指数(989001)24日跌0.29%
谷歌回应Bard内容“抄袭”:插入链接会打断对话
快资讯丨浙江2人遭雷击不幸身亡 急救中心发布雷雨天出行提示
0糖0脂肪 丘里福建大红袍、铁观音茶饮闭眼囤:券后6瓶15.8元
天天新动态:最远能跑333km 五菱缤果官宣3月29日上市:7万交个朋友?
认真做优化 Intel显卡驱动容量减少一半:从1.3GB降至0.6GB
天天速递!全国跳水冠军赛:昌雅妮成为女子3米板“双冠王 ”
环球快讯:MySQL错误ERROR 2003 (HY000) Can't connect to MySQL server .' (111)
CSP20230319-4 星际网络II 题解
焦点信息:DNF远古地下城怎么开
天天观点:抵制汽车行业网络水军!比亚迪、长城、蔚小理等发起联合倡议
萤石TV Studio发布:接管电视“大脑” 让一屏秒变三屏!
【世界快播报】灯座安装即插即用:萤石发布4G款灯座云台摄像机C8b
环球新动态:比亚迪宋Pro DM-i 2023款实车曝光:前脸大变 加长加高
【全球新视野】2023第三届大湾区数字峰会在广州召开
环球快看点丨开心档之Go 语言数据类型
C#中?.、??、?:、及?等符号用途
看热讯:泛型的学习
关于工作态度和责任心的句子有哪些?工作态度自我评价模板
燃野少年的天空老狗最后和谁在一起了?燃野少年的天空演员表
春联横批是从左到右还是从右到左?通用的春联横批大全
大玉儿是不是孝庄太后?大玉儿爱多尔衮还是皇太极?
郭晓婷和袁弘是什么关系?郭晓婷演过的电视剧有哪些?
比亚迪新专利获授权 通过手背静脉识别控制车辆
当前滚动:玩家搜集信息拼凑《GTA6》地图:比洛圣都要大3倍
腾讯把《和平精英》里的技术引入输入法和地图 1700万人受益
HTTP请求方法
每日聚焦:RTX 4080 Ti运行《暗黑破坏神4》变砖:暴雪与NVIIDIA进行联合调查
广州突降冰雹 车主晒特斯拉玻璃车顶快被砸烂
中国电竞酒店突破2万家:西安郑州最多 玩家不止玩游戏
13代标压i5还有军工级品质!华硕a豆14 2023笔记本评测:智能远控 直击痛点
被曝垃圾桶捞回食材上桌!网红店半天妖发布致歉声明
全球快讯:2023年八字运势查询 乙酉日柱事业好
环球快资讯:SaaS 营销,如何利用 RPA 实现自动化获客?
全球视点!保姆级教程!玩转 ChunJun 详细指南
python入门语法
灵感来自中国:俄罗斯电视台首次推出AI女主播
全球关注:“大嫂”高叶代言!《原始征途》手游公测:史玉柱亲自研发
每日快看:碳酸锂价格暴跌一半!特斯拉还会再降价?
环球要闻:支付宝首页能直接刷短视频了 新增“看一看”入口
票房全球第三 《阿凡达2》4K高清资源偷跑:容量13GB
2023江苏连云港市考试录用公安机关特殊专技职位公务员(人民警察)入围技能测试人选公告
热头条丨Lunabot让你在任何网站都能使用ChatGPT(亲测有效!!!)
世界微头条丨高铁餐食又上新了:星级酒店烹饪 30分钟极速送达 还是热的
世界观天下!半价大促:五芳斋豆沙青团6枚9.9元到手 清甜绵软
快消息!特斯拉Model 3标准续航版或失7500美元税收优惠:只因用了中国电池
全球观天下!本田大法还香吗?全新紧凑型SUV车型HR-V量产下线:或16万起售
当前短讯!索赔近2万维修费!老人故意推倒摩托车案今日开庭:车主起诉继承人
浙江铁塔为结对帮扶村送医送药暖民心
数据库系统原理之数据库设计
世界时讯:安全高效 | AIRIOT智慧工地管理解决方案
世界今头条!ChatGPT王炸更新!能联网获取新知识、可与5000+个应用交互:太疯狂了
国产科幻FPS大作来了!《边境》官宣4月14日正式发售
全球热资讯!深圳一兰博基尼车头被教练车撞瘪 驾校:车上有一学员