ORM多表更新刪除 查詢
阿新 • • 發佈:2020-07-21
刪除和修改
一對一和一對多的操作
# 修改和刪除操作 def edit_book(request): # 一對一修改 # 方式一: 通過模型類物件 au_det_obj = models.AuthorDetail.objects.get(id=3) models.Author.objects.filter(id=1).update(name="bob",ad=au_det_obj) # # 方式二 models.Author.objects.filter(id=5).update(name="jack",ad_id=1) # 一對多修改:同一對一# 方式一: pub_obj = models.Publish.objects.get(id=2) models.Book.objects.filter(id=6).update(pud=pub_obj) # 方式二: models.Book.objects.filter(id=7).update(pud_id=3) # 刪除: 注意級聯刪除關係, 相關的資料都會刪掉 models.Author.objects.get(id=1).delete() models.Author.objects.filter(id=3).delete() models.AuthorDetail.objects.filter(id=4).delete() return HttpResponse('OK')
多對多關係的刪除和更新
# 多對多的刪除和更新 # 刪除remove book_obj = models.Book.objects.get(id=1) book_obj.authors.remove(8) # 刪除一條 book_obj = models.Book.objects.get(id=6) book_obj.authors.remove(7, 8) # 刪除多條 # 清空clear book_obj = models.Book.objects.get(id=4) book_obj.authors.clear()# 更新 book_obj = models.Book.objects.get(id=3) book_obj.authors.set("7") # 引數是可迭代型別資料 # 更改多條 book_obj.authors.set([7,8,9]) # set動作有兩步:1 先執行clear 2 再執行add新增
多表查詢
基於物件的跨表查詢(子查詢)
正向查詢:關係屬性寫在哪個表裡面,那麼通過這個表的資料,去查詢關聯的另外一張表的資料,就叫做正向查詢,反之就是反向查詢
# 一對一正向查詢 # 查陳六六作者的電話號碼 author_obj = models.Author.objects.get(name="陳六六") # author_obj.ad 找到了author_obj關聯的作者詳細資訊表裡面對應記錄 print(author_obj.ad.telephore) # 777 # 反向查詢 : 反向查詢用關聯它的模型類的名稱小寫 # 查詢地址為北京的作者名稱 aut_det_obj = models.AuthorDetail.objects.get(address="四川") print(aut_det_obj.author.name) # 陳七七 # 一對多正向查詢 同一對一查詢 # 查詢人生是哪個出版社的 book_obj = models.Book.objects.get(title="人生") print(book_obj.pud.name) # 小樹出版社 # 反向查詢 模型類名小寫_set # 查詢小樹出版社出版哪些書 pub_obj = models.Publish.objects.get(name="小樹出版社") print(pub_obj.book_set.all()) # <QuerySet [<Book: Book object>, <Book: Book object>]> 類似於objects控制器 print(pub_obj.book_set.all().values("title")) # <QuerySet [{'title': '人生'}, {'title': '人類'}]> # 多對多查詢 # 正向查詢 使用屬性來查 # 查詢人生是誰寫的 book_obj = models.Book.objects.get(title="人生") print(book_obj.authors.all().values("name")) # <QuerySet [{'name': '陳六六'}, {'name': '陳七七'}, {'name': '張三'}]> # 反向查詢 使用模型類名小寫_set # 查詢陳六六寫了哪些書 author_obj = models.Author.objects.get(name="陳六六") print(author_obj.book_set.all().values("title")) # <QuerySet [{'title': '人間'}, {'title': '人生'}]> return HttpResponse('OK')
檢視原生SQL語句的方法
1 ORM語句.query
2 在settings配置檔案中寫上如下內容,就能夠自動打印出我們執行orm語句對應的sql語句 LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } } 3 通過django配置的連線mysql的管道來檢視(pymysql) from app01 import models def add_book(request): ''' 新增表記錄 :param request: http請求資訊 :return: ''' book_obj = models.Book(title='python',price=123,pub_date='2012-12-12',publish='人民出版社') book_obj.save() from django.db import connection #通過這種方式也能檢視執行的sql語句 print(connection.queries) return HttpResponse('ok')
# 一對一正向查詢 使用屬性 # 查詢陳七七作者的地址 res = models.Author.objects.filter(name="陳七七").values("ad__address") print(res) # <QuerySet [{'ad__address': '四川'}]> # 反向查詢 表名小寫 res = models.AuthorDetail.objects.filter(author__name="陳七七").values("address") print(res) # <QuerySet [{'address': '四川'}]> # 一對多正向查詢 # 查詢人世是哪個出版社的 res = models.Book.objects.filter(title="人世").values("pud__name") print(res) # <QuerySet [{'pud__name': '小草出版社'}]> # 反向操作 res = models.Publish.objects.filter(book__title="人世").values("name") print(res) # <QuerySet [{'name': '小草出版社'}]> # 多對多正向查詢 使用關聯屬性 # 查詢人類這本書是誰寫的 res = models.Book.objects.filter(title="人類").values("authors__name") print(res) # <QuerySet [{'authors__name': 'jack'}]> # 反向查詢 res = models.Author.objects.filter(book__title="人類").values("name") print(res) # <QuerySet [{'name': 'jack'}]>
# 聚合查詢 from django.db.models import Max, Min, Avg, Count, Sum # 統計一下所有書籍的平均價格 res = models.Book.objects.aggregate(Avg("price")) print(res) # {'price__avg': 62.757143} 結果是普通字典型別 # 可以起別名 res = models.Book.objects.aggregate(a=Avg("price"),b=Max("price")) print(res) # {'a': 62.757143, 'b': Decimal('99.90')} # aggregate方法可以看為是orm語句的結束語句,結果為普通字典型別,不能在繼續呼叫queryset或者模型類物件提供的方法了
# 分組查詢 必須制定別名 # 查詢一下每個出版社出版書的平均價格 from django.db.models import Max, Min, Avg, Count, Sum res = models.Book.objects.values("pud_id").annotate(a=Avg("price")) print(res) # <QuerySet [{'pud_id': 1, 'a': 99.9}, {'pud_id': 2, 'a': 39.9}, {'pud_id': 3, 'a': 59.9}]> res = models.Book.objects.values("pud_id","id").annotate(a=Avg("price")) print(res) # values裡面可以加多個分組條件 # 以出版社名稱分組的書的平均價格 res = models.Book.objects.values("pud__name").annotate(a=Avg("price")) print(res) # <QuerySet [{'pud__name': '小草出版社', 'a': 39.9}, {'pud__name': '小樹出版社', 'a': 59.9}, {'pud__name': '小花出版社', 'a': 99.9}]> res = models.Publish.objects.annotate(a=Avg("book__price")) print(res) # <QuerySet [<Publish: Publish object>, <Publish: Publish object>, <Publish: Publish object>]> # 返回結果是Publish的模型類物件,這個模型類物件裡面包含Publish的所有屬性資料,還有annotate的統計結果資料 ret = res.values("name","a") print(ret) # <QuerySet [{'name': '小草出版社', 'a': 39.9}, {'name': '小樹出版社', 'a': 59.9}, {'name': '小花出版社', 'a': 99.9}]>
# F查詢 # F查詢可以用來做本表不同欄位之間的一個比較 # 查詢點贊數大於評論數的書籍 from django.db.models import F res = models.Book.objects.filter(dianzan__gt=F("comment")) print(res) # <QuerySet [<Book: 人間>, <Book: 人生>, <Book: 人類>]> # F可以用來對本表資料進行一些統一操作(四則運算都支援) # 將所有的書籍上調10塊錢 models.Book.objects.all().update(price=F("price")+10)
# Q查詢 filter中的查詢條件預設是and關係 # 可以進行多條件查詢,查詢關係可以是 或與非 from django.db.models import Q # ~ 條件取反 ,&--and關係 ,|--or關係 # 查詢書名中包含以小開頭的,或者評論數在350以上的 res = models.Book.objects.filter(Q(title__startswith="小")|Q(comment__gt=350)) print(res) # <QuerySet [<Book: 小貓>, <Book: 貓生>, <Book: 小狗>]> # 查詢書名中包含小的,或者評論數在350以上的,並且點贊數大於400的 res = models.Book.objects.filter(Q(title__startswith="小")|Q(comment__gt=350),dianzan__gt=400) print(res) # <QuerySet [<Book: 貓生>, <Book: 小狗>]> # 注意,如果結合逗號來進行and的關係查詢,那麼必須將沒有Q包裹的查詢條件放在Q包裹的查詢條件後面 #下面這種方式也可以,Q查詢可以多層巢狀使用 res = models.Book.objects.filter(Q(title__startswith="小") | Q(comment__gt=350)&Q( dianzan__gt=400)) print(res) # <QuerySet [<Book: 小貓>, <Book: 貓生>, <Book: 小狗>]>