ORM 對錶操作 詳解

  • 2019 年 10 月 8 日
  • 筆記

目錄

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 給反向查詢的小寫表名起別名,以後反向查詢調用都用這個別名

作 者:郭楷豐