ORM 对表操作 详解
程序员文章站
2022-04-30 22:26:26
ORM对表操作详解 [TOC] 表结构 作者表,作者详细信息表,出版社表,书籍表 ORM对表的 增 删 改 查 增加 删 改 基于对象的跨表查询 类似于子查询 正向查询和反向查询 关系属性(字段)写在哪个类(表)里面,从当前类(表)的数据去查询它关联类(表)的数据叫做正向查询,反之叫做反向查询 OR ......
orm对表操作详解
表结构
作者表,作者详细信息表,出版社表,书籍表
from django.db import models # 作者表(一对一作者详细信息表) #比较常用的信息放到这个表里面 class author(models.model): name = models.charfield(max_length=32, verbose_name='作者姓名') age = models.integerfield(verbose_name='年龄') # authordetail=models.onetoonefield(to="authordetail",to_field="nid",on_delete=models.cascade) # #to关联表,to_field指定字段,on_delete设置级联删除 authordetail = models.onetoonefield(to='authordetail', verbose_name='作者详细信息') # 一对一到authordetail表 生成为表字段之后,会自动变为authordetail_id这样有一个名称 # onetoonefield(一对一关系) 相当于 foreign+unique def __str__(self): return self.name # 作者详细信息表 class authordetail(models.model): birthday = models.datefield(verbose_name='出生日期') # telephone=models.bigintegerfield()#不方便查询,比如模糊查询,占资源比较多 telephone = models.charfield(max_length=32, verbose_name='电话') # charfield推荐使用来存储电话 addr = models.charfield(max_length=64, verbose_name='住址') def __str__(self): return self.addr # 出版社表 #(一对多 书籍表)是 class publish(models.model): name = models.charfield(max_length=32, verbose_name='出版社名称') city = models.charfield(max_length=32, verbose_name='出版社所在城市') email = models.emailfield(verbose_name='出班社邮箱') # emailfield本质上是charfield做了一些邮箱规则的效验 def __str__(self): return self.name # 书籍表 class book(models.model): nid = models.autofield(primary_key=true) title = models.charfield(max_length=32, verbose_name='书名') publishdate = models.datefield(verbose_name='出版日期') price = models.decimalfield(max_digits=5, decimal_places=2, verbose_name='价格') # max_digits小数总位数,decimal_places小数部分位数 publishs = models.foreignkey(to="publish", verbose_name='出版社') authors = models.manytomanyfield(to='author', verbose_name='作者') def __str__(self): return self.title
orm对表的 增 删 改 查
增加
一对一 models.author.objects.create(name='xx',age=18,authordetail=mdoels.authordetail.objects.get(id=1)) models.author.objects.create(name='xx',age=18,authordetail_id=2) 一对多 models.book.objects.create(xx=xx,publishs=mdoels.publish.objects.get(id=1)) models.book.objects.create(xx=xx,publishs_id=2) 多对多 book_obj = models.book.objects.get(id=1) book_obj.authors.add(*[author_obj1,author_obj2,..]) book_obj.authors.add(*[1,2,3...])
删
一对一 models.author.objects.filter(id=1).delete() 一对多 models.book.objects.filter(id=1).delete() 多对多 book_obj = models.book.objects.get(id=1) book_obj.authors.remove(1,2,3,4) book_obj.authors.remove(*[1,2,...]) book_obj.authors.clear() book_obj.authors.set(['1','2',...]) :clear -- add
改
一对一 models.author.objects.filter(id=1).update( authordetail=mdoels.authordetail.objects.get(id=1) ) models.author.objects.filter(id=1).update( authordetail_id=2, ) 一对多 models.book.objects.filter(id=1).update( publishs=mdoels.publish.objects.get(id=1) ) models.book.objects.filter(id=1).update( publishs_id=2, ) 多对多 book_obj.authors.set(['1','2',...]) :clear -- add
基于对象的跨表查询 -- 类似于子查询
正向查询和反向查询
- 关系属性(字段)写在哪个类(表)里面,从当前类(表)的数据去查询它关联类(表)的数据叫做正向查询,反之叫做反向查询
#查询 # 一对一 # 正向查询 #1 查询崔老师的电话号 # author_obj = models.author.objects.filter(name='崔老师').first() # # print(author_obj.authordetail) #辽宁峨眉山 # # print(author_obj.authordetail.telephone) #444 # #2 反向查询 # #2 查询一下这个444电话号是谁的. # author_detail_obj = models.authordetail.objects.get(telephone='444') # print(author_detail_obj.author) #崔老师 # print(author_detail_obj.author.name) #崔老师 ''' 正向查询:authorobj.authordetail,对象.关联属性名称 author----------------------------------->authordetail <----------------------------------- 反向查询:authordetailobj.author ,对象.小写类名 ''' # 一对多 # 查询一下李帅的床头故事这本书的出版社是哪个 # 正向查询 book_obj = models.book.objects.get(title='李帅的床头故事') print(book_obj.publishs) #b哥出版社 print(book_obj.publishs.name) #b哥出版社 # b哥出版社出版社出版了哪些书 # 反向查询 pub_obj = models.publish.objects.get(name='b哥出版社') print(pub_obj.book_set.all()) #<queryset [<book: 李帅的床头故事>, <book: 李帅的床头故事2>]> ''' 正向查询 book_obj.publishs 对象.属性 book ---------------------------------------------> publish <---------------------------------------------- 反向查询 publish_obj.book_set.all() 对象.表名小写_set ''' # 多对多 # 李帅的床头故事这本书是谁写的 # 正向查询 book_obj = models.book.objects.get(title='李帅的床头故事') print(book_obj.authors.all()) # 高杰写了哪些书 author_obj = models.author.objects.get(name='高杰') print(author_obj.book_set.all()) ''' 正向查询 book_obj.authors.all() 对象.属性 book ---------------------------------------------> author <---------------------------------------------- 反向查询 author_obj.book_set.all() 对象.表名小写_set '''
基于双下划綫的跨表查询 -- 连表 join
- 正向查询和反向查询
#查询 # 一对一 # 1. 查询崔老师的电话号 # 方式1 正向查询 # obj = models.author.objects.filter(name='崔老师').values('authordetail__telephone') # print(obj) #<queryset [{'authordetail__telephone': '444'}]> # 方式2 反向查询 # obj = models.authordetail.objects.filter(author__name='崔老师').values('telephone','author__age') # print(obj) #<queryset [{'telephone': '444'}]> # 2. 哪个老师的电话是444 # 正向 # obj = models.author.objects.filter(authordetail__telephone='444').values('name') # print(obj) # 反向 # obj = models.authordetail.objects.filter(telephone='444').values('author__name') # print(obj) # 一对多 # 查询一下李帅的床头故事这本书的出版社是哪个 # obj = models.book.objects.filter(title='李帅的床头故事').values('publishs__name') # print(obj) #<queryset [{'publishs__name': 'b哥出版社'}]> # obj = models.publish.objects.filter(book__title='李帅的床头故事').values('name') # obj = models.publish.objects.filter(xx__title='李帅的床头故事').values('name') # print(obj) # b哥出版社出版社出版了哪些书 # obj = models.publish.objects.filter(name='b哥出版社').values('book__title') # print(obj) #<queryset [{'book__title': '李帅的床头故事'}, {'book__title': '李帅的床头故事2'}]> # obj = models.book.objects.filter(publishs__name='b哥出版社').values('title') # print(obj) #<queryset [{'title': '李帅的床头故事'}, {'title': '李帅的床头故事2'}]> # 李帅的床头故事这本书是谁写的 # obj = models.book.objects.filter(title='李帅的床头故事').values('authors__name') # print(obj) # obj = models.author.objects.filter(book__title='李帅的床头故事').values('name') # print(obj) #<queryset [{'name': '高杰'}, {'name': '崔老师'}]> #高杰写了哪些书 # obj = models.book.objects.filter(authors__name='高杰').values('title') # print(obj) # obj = models.author.objects.filter(name='高杰').values('book__title') # print(obj) #进阶的 # b哥出版社 出版的书的名称以及作者的名字 # obj = models.book.objects.filter(publishs__name='b哥出版社').values('title','authors__name') # print(obj) #<queryset [{'title': '李帅的床头故事', 'authors__name': '高杰'}, {'title': '李帅的床头故事', 'authors__name': '崔老师'}, {'title': '李帅的床头故事2', 'authors__name': '崔老师'}, {'title': '李帅的床头故事2', 'authors__name': '王涛'}]> ''' select app01_book.title,app01_author.name from app01_publish inner join app01_book on app01_publish.id=app01_book.publishs_id inner join app01_book_authors on app01_book.nid = app01_book_authors.book_id inner join app01_author on app01_author.id = app01_book_authors.author_id where app01_publish.name='b哥出版社'; :param request: :return: ''' # obj = models.publish.objects.filter(name='b哥出版社').values('book__title','book__authors__name') # print(obj) # obj = models.author.objects.filter(book__publishs__name='b哥出版社').values('name','book__title') # print(obj) # authordetail author book publish # 手机号以4开头的作者出版过的所有书籍名称以及出版社名称 # ret = models.authordetail.objects.filter(telephone__startswith='4').values('author__book__title','author__book__publishs__name') # print(ret) #queryset [{'author__book__title': '李帅的床头故事', 'author__book__publishs__name': 'b哥出版社'}, {'author__book__title': '李帅的床头故事2', 'author__book__publishs__name': 'b哥出版社'}]> #查询一下b哥出版社出版了哪些书 # obj = models.publish.objects.filter(name='b哥出版社').first() # print(obj.xx.all())
orm对表的操作示例
操作示例 点击查看(代码)
system.out.println("hello to see u!"); ```python 1.1 一对一增加 new_author_detail = models.authordetail.objects.create( birthday='1979-08-08', telephone='138383838', addr='黑龙江哈尔滨' ) obj = models.authordetail.objects.filter(addr='山西临汾').first() 方式1 models.author.objects.create( name='王涛', age='40', authordetail=new_author_detail, ) 方式2 常用 models.author.objects.create( name='王涛', age='40', authordetail_id=obj.id, ) 1.2 一对多增加 方式1 obj = models.publish.objects.get(id=2) models.book.objects.create( title = '李帅的床头故事', publishdate='2019-07-22', price=3, # publishs=models.publish.objects.get(id=1), publishs=obj, ) 方式2 常用 models.book.objects.create( title='李帅的床头故事2', publishdate='2019-07-21', price=3.5, # publishs=models.publish.objects.get(id=1), publishs_id=obj.id ) 1.3 多对多增加 方式1 常用(效率高) book_obj = models.book.objects.get(nid=1) book_obj.authors.add(*[1,2]) 方式2 author1 = models.author.objects.get(id=1) author2 = models.author.objects.get(id=3) book_obj = models.book.objects.get(nid=5) book_obj.authors.add(*[author1,author2]) ``` ### orm对表的 删 操作 ```python #一对一 和 一对多 的删除和单表删除是一样的. #一对一 表一外键关联到表二,表一删除,不影响表2,表2删除会影响表1 models.authordetail.objects.get(id=2).delete() models.author.objects.get(id=3).delete() 一对多 models.publish.objects.get(id=1).delete() models.book.objects.get(nid=1).delete() 多对多关系删除 book_obj = models.book.objects.get(nid=6) book_obj.authors.remove(6) #authors是表中的关联对象 删除单个 book_obj.authors.remove(*[5,6]) #删除多个 book_obj.authors.clear() #全部关联对象删除 book_obj.authors.add(*[1,]) #添加 book_obj.authors.set('1') #删除之前关系添加新关系 book_obj.authors.set(['5','6']) #删除然后更新 多个 ``` ### orm对表的 更新 操作 ```python 一对一 更新 models.author.objects.filter(id=5).update( name='崔老师', age=16, # authordetail=models.authordetail.objects.get(id=5), authordetail_id=4, ) 一对多 更新 models.book.objects.filter(pk=4).update( title='b哥的往事2', # publishs=models.publish.objects.get(id=3), publishs_id=3, ) #一对多 models.publish.objects.filter(pk=2).update( id=4, # 没有级联更新,报错!! ) ``` ### orm对表的 查询 操作(重点 ) ```python #查询 # 一对一 # 1. 查询崔老师的电话号 # 方式1 正向查询 # obj = models.author.objects.filter(name='崔老师').values('authordetail__telephone') # print(obj) # #方式2 反向查询 # obj = models.authordetail.objects.filter(author__name='崔老师').values('telephone','author__age') # print(obj) # # 2. 哪个老师的电话是444 # 正向 # obj = models.author.objects.filter(authordetail__telephone='444').values('name') # print(obj) # 反向 # obj = models.authordetail.objects.filter(telephone='444').values('author__name') # print(obj) # 一对多 # 查询一下李帅的床头故事这本书的出版社是哪个 # obj = models.book.objects.filter(title='李帅的床头故事').values('publishs__name') # print(obj) # obj = models.publish.objects.filter(book__title='李帅的床头故事').values('name') # print(obj) # b哥出版社出版社出版了哪些书 # obj = models.publish.objects.filter(name='b哥出版社').values('book__title') # print(obj) # # obj = models.book.objects.filter(publishs__name='b哥出版社').values('title') # print(obj) # # 李帅的床头故事这本书是谁写的 # obj = models.book.objects.filter(title='李帅的床头故事').values('authors__name') # print(obj) # obj = models.author.objects.filter(book__title='李帅的床头故事').values('name') # print(obj) # # 高杰写了哪些书 # obj = models.book.objects.filter(authors__name='高杰').values('title') # print(obj) # obj = models.author.objects.filter(name='高杰').values('book__title') # print(obj) # 进阶的 # b哥出版社 出版的书的名称以及作者的名字 # obj = models.book.objects.filter(publishs__name='b哥出版社').values('title','authors__name') # print(obj) # ''' select app01_book.title,app01_author.name from app01_publish inner join app01_book on app01_publish.id=app01_book.publishs_id inner join app01_book_authors on app01_book.nid = app01_book_authors.book_id inner join app01_author on app01_author.id = app01_book_authors.author_id where app01_publish.name='b哥出版社'; :param request: :return: ''' # obj = models.publish.objects.filter(name='b哥出版社').values('book__title','book__authors__name') # print(obj) # obj = models.author.objects.filter(book__publishs__name='b哥出版社').values('name','book__title') # print(obj) # authordetail author book publish # 手机号以4开头的作者出版过的所有书籍名称以及出版社名称 # ret = models.authordetail.objects.filter(telephone__startswith='4').values('author__book__title','author__book__publishs__name') # print(ret) # queryset [{'author__book__title': '李帅的床头故事', 'author__book__publishs__name': 'b哥出版社'}, {'author__book__title': '李帅的床头故事2', 'author__book__publishs__name': 'b哥出版社'}]> # 查询一下b哥出版社出版了哪些书 # obj = models.publish.objects.filter(name='b哥出版社').first() # print(obj.xx.all()) ```
正向查 与 反向查
正向查反向查(从设置表关系的那张表查另一张就是正向,反之就是反向查)
related_name 给反向查询的小写表名起别名,以后反向查询调用都用这个别名
作 者:
出 处:
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角 【推荐】一下。您的鼓励是博主的最大动力!
自 勉:生活,需要追求;梦想,需要坚持;生命,需要珍惜;但人生的路上,更需要坚强。带着感恩的心启程,学会爱,爱父母,爱自己,爱朋友,爱他人。
上一篇: 今日份尴尬
下一篇: 从“约瑟夫问题”谈起