ORM關聯表模型

ORM關聯表模型python

1、建立表git

1.一對一:sql

1 class Author(models.Model): 2 nid = models.AutoField(primary_key=True) 3 name=models.CharField( max_length=32) 4 age=models.IntegerField() 5 6 # 與AuthorDetail創建一對一的關係,外鍵隨便在哪一方 7 authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE) #生成一對一或一對多的外鍵時必須加on_delete=models.CASCADE 8 #注意!!!必寫:on_delete=models.CASCADE:刪除關聯數據,與之關聯也刪除

2.一對多:django

1 class Book(models.Model): 2 3 nid = models.AutoField(primary_key=True) 4 title = models.CharField( max_length=32) 5 publishDate=models.DateField() 6 price=models.DecimalField(max_digits=5,decimal_places=2) 7 8 # 與Publish創建一對多的關係,外鍵字段創建在多的一方(多的一方對應少的一個) 9 publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)

3.多對多:函數

 1 class Book(models.Model):  2  3 nid = models.AutoField(primary_key=True)  4 title = models.CharField( max_length=32)  5 publishDate=models.DateField()  6 price=models.DecimalField(max_digits=5,decimal_places=2)  7  8  9 # 與Author表創建多對多的關係,ManyToManyField能夠建在兩個模型中的任意一個,自動建立第三張表 10 authors=models.ManyToManyField(to='Author',)

2、添加表數據:spa

1.一對多:翻譯

 1    #單表添加記錄(沒有任何關聯)  2 pub = Publish.objects.create(name="人民出版社", city="北京", email="123@qq.com")  3  4 #爲book表綁定關係:publish  5 #方式一:  6 book_obj = Book.objects.create(title="紅樓夢", publishDate="2018-05-06", price="200", publish_id=1)  7 print(book_obj.title) # 返回值book_obj爲插入的這條數據的對象  8 # 方式二:  9 publish = Publish.objects.filter(nid=1).first() # 拿到nid=1的queryset,只有加了first纔在列表中拿到第一個對象 10 book_obj = Book.objects.create(title="水滸傳", publishDate="2522-01-06", price="500", publish=publish) 11 print(book_obj.title) # 返回值book_obj爲插入的這條數據的對象 12 print(book_obj.publish) # 與這本書關聯的出版社的對象:Publish object (1) 13 print(book_obj.publish_id) # 打印publish_id 14 print(book_obj.publish.name) 15 print(book_obj.publish.city) 16 17 return HttpResponse("OK")

2.多對多:code

 1 '''-----------------------------綁定多對多的關係-------------------------------'''  2  3 #建立數據  4 book_obj = Book.objects.create(title="金2", publishDate="1920-11-22", price=50, publish_id=2)  5  6 # 爲書籍綁定的作做者對象  7 alex=Author.objects.filter(name="alex").first() # 在Author表中主鍵爲2的紀錄  8 egon=Author.objects.filter(name="egon").first() # 在Author表中主鍵爲1的紀錄  9 10 11 # 綁定多對多關係,即向關係表book_authors中添加紀錄 12 #pycharm提供的接口找到多對多關係的表,book_obj(添加數據的對象).authors(在建立表類的時候ManytoManyField開的接口).add() 13 book_obj.authors.add(alex, egon) # 將某些特定的 model 對象添加到被關聯對象集合中。 ======= book_obj.authors.add(*[]) 14 book_obj.authors.add(1,2) # 能夠直接添加主鍵 15 book_obj.authors.add(*[1,2,3]) # 給函數添加列表要在前面加*

3.解除多對多關係:對象

1 #解除多對多的關係 2 #解除的前提:先查到一個數據,找對應數據解除 3 book_obj = Book.objects.filter(nid=9).first() 4 # book_obj.authors.remove(2) # book_obj=9,authors=2,解除關係9-2 5 # 6 # book_obj.authors.clear() # 清空被關聯對象集合,只要book_id=4所有清除 7 8 print(book_obj.authors.all()) #類型:queryset 獲取全部book_obj關聯的做者對象的集合 9 print(book_obj.authors.all().value("name")) # 拿到author的名字

3、跨表查詢blog

1.基於對象的查詢------->子查詢

一對多:

 1 A-B  2  3 正向查詢:關聯屬性在A表中 A--->B  4 反向查詢:關聯屬性在A表中 B--->A  5  6  7  一對多查詢:  8  正向查詢按字段  9  反向查詢安表名小寫_set.all() 10 11  (正)book_obj.publish 12 Book(關聯屬性:publish) --------------> Publish 13 (反)book_set.all() #queryset

實例:

  (1)一對多正向查詢:

1 #一對多正向查詢:查詢金這本書的出版社名字 2 3 book_obj = Book.objects.filter(title="").first() 4 print(book_obj.publish.name) # 與這本書關聯的出版社對象,的名字

  (2)一對多反向查詢:

1 #一對多反向查詢:查詢人民出版社出版過的書籍名稱 2 publish = Publish.objects.filter(name="人民出版社").first() 3 print(publish.book_set.all()) # 拿到書籍對象的集合queryset

多對多:

1  多對多查詢: 2  正向查詢按字段.all() 3  反向查詢安表名小寫_set.all() 4 5  (正)book_obj.authors.all() 6 Book(關聯屬性:publish) ------------------------> Author 7 (反)book_set.all() #queryset

實例:

  (1)多對多正向查詢:

1 #多對多正向查詢:查詢金這本書的全部做者名字 2 book_obj = Book.objects.filter(title="").first() 3 author_list = book_obj.authors.all() # queryset 4 5 for author in author_list: # 循環queryset拿到每個object 6 print(author.name) # 調用對象下的屬性

  (2)多對多反向查詢:

1 # 多對多反向查詢:查詢alex出版過的全部書籍名稱 2 author_obj = Author.objects.filter(name="alex").first() 3 book_list = author_obj.book_set.all() 4 5 for book in book_list: 6 print(book.title)

一對一:

1  一對一查詢: 2  正向查詢按字段 3  反向查詢按表名 4 5  (正)author_obj.authordetail 6 Author(關聯屬性:authorDetail) ------------------------> AuthorDetail 7 (反)authordetail_obj.author

實例:

  (1)一對一正向查詢:

1 # 一對一正向查詢:查詢alex的手機號 2 alex = Author.objects.filter(name="alex").first() 3 print(alex.authordetail.telephone)

  (2)一對一反向查詢:

1 # 一對一反向查詢:查詢手機號爲110的做者名 2 phone = AuthorDetail.objects.filter(telephone=110).first() 3 print(phone.author.name)

2.基於雙下劃線查詢:

  步驟:

    00.記住格式:表名.object.filter(表名小寫="").value("")

    01.找到問題的切入點,找到一個表的對象當主對象,例如:Book.object

    02.看主對象是否有可以直接找到的本表數據,若是有,則在filter中獲取,若是則在value裏查找

    03.用__進行跨表操做

案例:

 1 #一對多查詢:查詢金這本書的出版社名字  2 #方式一  3 ret = Book.objects.filter(title="").values("publish__name")  4 print(ret) # <QuerySet [{'publish__name': '北京出版社'}]>  5  6 #方式二  7 ret = Publish.objects.filter(book__title="").values("name")  8 print(ret)  9 10 11 #多對多查詢:查詢金這本書的全部做者名字 12 13 #方式一: 14 ret = Book.objects.filter(title="").values("authors__name") 15 print(ret) # <QuerySet [{'authors__name': 'egon'}]> 16 17 18 #方式二: 19 ret = Author.objects.filter(book__title="").values("name") 20 print(ret) # <QuerySet [{'name': 'egon'}]> 21 22 23 24 #一對一查詢:查詢alex手機號 25 ret = Author.objects.filter(name="alex").values("authordetail__telephone") 26 print(ret)

3.基於下劃線的跨表查詢(連續跨表)

實例:

1 #手機號以110開頭的做者出版過的全部書籍名稱以及書籍出版社名稱 2 #方法一 3 ret = Book.objects.filter(authors__authordetail__telephone__startswith="110").values("title","publish__name") 4 print(ret) 5 6 #方法二: 7 ret = Author.objects.filter(authordetail__telephone__startswith="110").values("book__title","book__publish__name") 8 print(ret)

4.聚合查詢

  (1)聚合(aggregate) 返回值:字典,而不是queryset

      實例:

1 #查詢全部書籍的平均價格 2 from django.db.models import Avg, Max, Min, Sum, Count 3 ret = Book.objects.all().aggregate(Avg("price"), Max("price")) # 可設置字典的key:avg_price=("屬性")_ 4 print(ret) # {'price__avg': 205.555556}

  (2)分組查詢(annotate) 返回值:queryset

      實例:

 1 #單表分組查詢  2  3 #查詢每個出版社所在成熟的個數  4 ret = Publish.objects.values("name").annotate(Count("city"))  5 print(ret) # 一個queryset的字典:  6 # <QuerySet [{'name': '人民出版社', 'city__count': 1}, {'name': '北京出版社', 'city__count': 1}, {'name': '上海出版社', 'city__count': 1}]>  7 '''  8  單表分組查詢的ORM語法:單表模型.objects.values("group by 的字段").annotate(聚合函數("統計字段"))  9 10  補充知識: 11  ret = Publish.objects.all() =====翻譯成sql語句===== select * from publish 12  只要包含主鍵的分組,那麼這個分組都毫無心義 13  ret = Publish.objects.values("name") =====翻譯成SQL語句===== select name from publish 14 15 16 ''' 17 18 19 #多表分組查詢 20 21 #查詢每個出版社出版的書籍幾個數 22 Book.objects.values("publish_id").annotate(c=Count("nid")) 23 24 #案例一:查詢每個出版社的名稱以及出版的數幾個數 25 #方式一: 26 Publish.objects.values("name").annotate(Count("book__title")) 27 #方式二:用表的主鍵id進行分組,再在分組後,整個關聯的表中再進行values的select操做 28 Publish.objects.values("nid").annotate(c = Count("book__title")).values("name","c") 29 30 #案例二:查詢每個做者價格最高的書籍 31 ret = Author.objects.values("pk").annotate(max_price=Max("book_price")).values("name","max_price") # pk爲該表模型的主鍵 32 33 #案例三:查詢每個書籍的名稱以及對應的做者個數 34 35 ret = Book.objects.values("pk").annotate(c = Count("authors__name")).values("title","c") 36 37 #案例四:統計不止一個做者的圖書 38 ret = Book.objects.values("pk").annotate(c=Count("author__name")).filter(c__gt=1).values("title") 39 print(ret)

分組查詢總結:

1  跨表的分組查詢模型:三套模型效果同樣 2 01.「每個」字段後表的模型.objects.values("pk").annotate(聚合函數("關聯表__統計字段")).values("表模型的全部字段以及統計字段") 3 02.「每個」字段後表的模型.objects.all().annotate(聚合函數("關聯表__統計字段")).values("表模型的全部字段以及統計字段") 4 03.「每個」字段後表的模型.objects.annotate(聚合函數("關聯表__統計字段")).values("表模型的全部字段以及統計字段")

5.F查詢與Q查詢

  (1)F查詢:

    應用場景:以前構造的過濾器filter都只是將字段值與某個常量作比較。若是咱們要對兩個字段的值作比較

    做用:F() 的實例能夠在查詢中引用字段,來比較同一個 model 實例中兩個不一樣字段的值

    前提:from django.db.models import F

    實例:

 1 # 查詢評論數大於收藏數的書籍  2  3 from django.db.models import F  4 Book.objects.filter(commnetNum__lt=F('keepNum'))  5  6 # Django 支持 F() 對象之間以及 F() 對象和常數之間的加減乘除和取模的操做。  7  8 # 查詢評論數大於收藏數2倍的書籍  9 Book.objects.filter(commnetNum__lt=F('keepNum')*2) 10 11 # 修改操做也可使用F函數,好比將每一本書的價格提升30元: 12 Book.objects.all().update(price=F("price")+30)

  (2)Q查詢:

    應用場景:filter() 等方法中的關鍵字參數查詢都是一塊兒進行「AND」 的。

    做用:若是你須要執行更復雜的查詢(例如OR 語句),你可使用Q 對象

    前提:from django.db.models import Q

    實例:

 1 Q 對象可使用& 和| 操做符組合起來。當一個操做符在兩個Q 對象上使用時,它產生一個新的Q 對象。  2  3 bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon"))  4 等同於下面的SQL WHERE 子句:  5  6 WHERE name ="yuan" OR name ="egon"  7 你能夠組合& 和| 操做符以及使用括號進行分組來編寫任意複雜的Q 對象。同時,Q 對象可使用~ 操做符取反,這容許組合正常的查詢和取反(NOT) 查詢:  8  9 bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title") 10 查詢函數能夠混合使用Q 對象和關鍵字參數。全部提供給查詢函數的參數(關鍵字參數或Q 對象)都將"AND」在一塊兒。可是,若是出現Q 對象,它必須位於全部關鍵字參數的前面。例如: 11 12 bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),title__icontains="python")

注意!!!爲已經建立的表增長新的字段須要設置default=0,例如:

1 read_num = models.IntegerField(default=0) 2 comment_num = models.IntegerField(default=0)
相關文章
相關標籤/搜索