一、ORM生成關聯模型

  (1) 一對一:表示和AuthorDetail這張表的nid構成關聯,一對一在人任意一張表構建關聯都可以,on_delete類似于mysql的關聯刪除

publish = models.OneToOneField(to='AuthorDetail',to_field='nid',on_delete=models.CASCADE)

    (2)    一對多:表示和publish這張表的nid構成關聯,一對多要在多的那張表構建關聯

publish = models.ForeignKey(to="publish",to_field="nid",on_delete=models.CASCADE)

    (3) 多對多:在一張表下(例如book)寫這段代碼,那么會自動生成一張表,表明為book_author(由book和變量author拼成),里邊有book_id,Author_id,以及2個關聯外鍵。

    author = models.ManyToManyField(to='Author')

  一對一和一對多都會在執行代碼的那張表里添加外鍵字段,多對多則是新生成一張表。

二、多表操作

  (1)添加

    1:一對多:  

方式1:通過自己寫

 Book.objects.create(title='小說1',price=100,publishDate='2020-9-9',publish_id=1)

方式2:通過對象傳

pub_obj = Publish.objects.filter(id=1).first()
Book.objects.create(title='小說1',price=100,publishDate='2020-9-9',publish=pub_obj)

    2:一對一:和一對多基本一樣

    3:多對多:先生成一個book對象,然后通過add構建book和author的關聯,其自動會在book_author表中添加關聯。 

book_obj=Book.objects.create(title='小說2',price=100,publishDate='2020-9-9',publish_id=2)
author1 = Author.object.get(name='author1'
author2 = Author.object.get(name='author2')
book_obj.author.add(author1,author2)#author為多對多字段變量名稱(manytomany那個)
#book_obj.author.add(1,2,3)

    解除關聯:

    book = Book.objects.filter(nid=4).first()
    book.author.remove(1,2,3)
    #等價于book.author.remove(*[1,2,3]) 
    #book.author.clear() 清除所有

  (2)查詢

    正向查詢:從關聯屬性所在的表去查詢,用字段

    反向查詢:反之,用name_set,其中name為表名

     1:基于對象

       一對多:

          正:查詢xx的出版社

     

    book_obj = Book.objects.filter(title='xx').first()
    print(book_obj.publish)
    print(book_obj.publish.name)

          反:查詢xx出版社出版過的書籍

    publish = Publish.objects.filter(name='xx').first()
    ret = publish.book_set.all()
    print(ret)

       多對多:

          正:查詢ss的作者名

book_obj = Book.objects.filter(title='ss').first()
author_list = book_obj.author.all()
for author in author_list:
print(author.name)

          反:查詢ss出版過的書籍

    ss = Author.objects.filter(name='ss').first()
    book_list = ss.book_set.all()
    for book in book_list:
        print(book.title)

       一對一:

          正:查詢作者p1的電話

    p1 = Author.objects.filter(name='p1').first()
    print(p1.authordetail.telephone)

          反:查詢電話為199的作者年齡

    phone = AuthorDetail.objects.filter(phone='199').first()
    print(phone.author.age)

     2:基于雙下劃線(join)

    正向查詢:從關聯屬性所在的表去查詢,用字段

    反向查詢:反之,用表名小寫,代表聯表。

       一對多:

          正:查詢xx的出版社名


  ret = Book.objects.filter(title='xx').values('publish__name') print(ret) #返回的是queryset對象列表

          反: 查詢xx的出版社名

  ret = Publish.objects.filter(book__title='xx').values('name')#方法二
  print(ret)

       多對多:

          正:查詢xx的作者名

    ret = Book.objects.filter(title='xx').values('author__name')
    print(ret)

          反:查詢xx的作者名

 ret = Author.objects.filter(book_title='xx').vaules('name')
    print(ret)

        一對一:查詢xx手機號

          正:查詢xx的手機號

    ret = Author.objects.filter(name='xx').vaules('authordetail_phone')
    print(ret)

          反:查詢xx的手機號

    ret = AuthorDetail.objects.filter(author__name='xx').values('phone')
    print(ret)

     連續跨表:查詢手機號以199開頭的作者出版過的書籍以及對應出版社名

方式1:

    ret = Book.objects.filter(author__authordetail__phone__startwith='119').values('title','publish__name')
    print(ret)

    聯接了author,authordetail,book,以及publish的表。

方式2:

    ret = Author.objects.filter(authordetail__phone__startwith='119').values('book__title','book__publish__name')
    print(ret)

     3:聚合

       有Max,Min,Count,Avg等函數

例子:計算所有書的平均價格

   ret = Book.objects.all().aggregate(Avg('price'))
   print(ret)

     4:分組

        1:單表

       例子: 查詢每一個部門的名稱以及員工的平均薪水。 

   from django.db.models import Avg,Max,Min,Count
  ret = emp.objects.values('dep').annotate(avg_salary=Avg('salary'))
   print(ret)

        2:多表

   from django.db.models import Avg,Max,Min,Count
   ret = Publish.objects.values('nid').annotate(c=Count("book__title")).vaules('name','c')
   print(ret)

 

     5:F與Q

     補充:ORM新增字段遷移時,要設置默認值default

      F查詢主要是表內部字段之間進行gt,lt、=,對比時使用的。因為默認python是找不到數據庫的對比字段的。

   from django.db.models import F,Q
   ret = Book.objects.filter(num1__gt=F('num2'))
   ret = Book.objects.all().update(price=F('price')*2)

     Q查詢主要是支持與或非選項。&、|、~,默認django是與操作。

 例子:找出名字不是xx,并且價格為100或200的書籍

from django.db.models import F,Q
ret = Book.objects.filter(~Q(title='xx')&Q(price=100)|Q(price=200))