欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ORM 对表操作 详解

程序员文章站 2022-08-20 14:07:13
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 对表操作 详解

ORM 对表操作 详解

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())
```

正向查 与 反向查

  • 正向查反向查(从设置表关系的那张表查另一张就是正向,反之就是反向查)

ORM 对表操作 详解

ORM 对表操作 详解

作 者:
出 处:
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角 推荐一下。您的鼓励是博主的最大动力!
自 勉:生活,需要追求;梦想,需要坚持;生命,需要珍惜;但人生的路上,更需要坚强。带着感恩的心启程,学会爱,爱父母,爱自己,爱朋友,爱他人。