ORM執行SQL語句
有時候ORM的操作效率可能偏低 我們是可以自己編寫SQL的
方式1:
raw()方法執行原生sql語句
models.User.objects.raw('select * from app01_user;')
方式2:
直接執行自定義原生sql(完全避開模型層,類似pymysql操作)
from django.db import connection
cursor = connection.cursor()
cursor.execute('select name from app01_user;')
print(cursor.fetchall())
神奇的雙下劃線查詢
只要還是queryset物件就可以無限制的點queryset物件的方法
queryset.filter().values().filter().values_list().filter()...
查詢年齡大於18的使用者資料
res = models.User.objects.filter(age__gt=18)
print(res)
查詢年齡小於38的使用者資料
res = models.User.objects.filter(age__lt=38)
print(res)
大於等於 小於等於
res = models.User.objects.filter(age__gte=18)
res = models.User.objects.filter(age__lte=38)
查詢年齡是18或者28或者38的資料
res = models.User.objects.filter(age__in=(18, 28, 38))
print(res)
查詢年齡在18到38範圍之內的資料
res = models.User.objects.filter(age__range=(18, 38))
print(res)
查詢名字中含有字母j的資料
區分大小寫
res = models.User.objects.filter(name__contains='j')
print(res)
不區分大小寫
res = models.User.objects.filter(name__icontains='j')
print(res)
查詢註冊年份是2022的資料
res = models.User.objects.filter(register_time__year=2022)
print(res)
針對django框架的時區問題 是需要配置檔案中修改的 後續bbs講解
ORM外來鍵欄位的建立
複習MySQL外來鍵關係
一對多
外來鍵欄位建在多的一方
多對多
外來鍵欄位統一建在第三張關係表
一對一
建在任何一方都可以 但是建議建在查詢頻率較高的表中
總結:關係的判斷可以採用換位思考原則
ORM外來鍵欄位建立
第一步:建立庫修改配置檔案連線資料庫
第二步:建立基礎表(書籍表、出版社表、作者表、作者詳情)
第三步:確定外來鍵關係
一對多 ORM與MySQL一致 外來鍵欄位建在多的一方
多對多 ORM比MySQL有更多變化
- 外來鍵欄位可以直接建在某張表中(查詢頻率較高的)
內部會自動幫你建立第三張關係表 - 自己建立第三張關係表並建立外來鍵欄位
一對一 ORM與MySQL一致 外來鍵欄位建在查詢較高的一方
執行遷移命令連線資料庫
第四步:ORM建立
針對一對多和一對一同步到表中之後會自動加_id的字尾
publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
針對多對多 不會在表中有展示 而是建立第三張表
authors = models.ManyToManyField(to='Author')
外來鍵欄位相關操作
前期準備(給表錄入一些資料)
針對一對多 插入資料可以直接填寫表中的實際欄位
models.Book.objects.create(title='三國演義', price=888.88, publish_id=1)
models.Book.objects.create(title='人性的弱點', price=777.55, publish_id=1)
針對一對多 插入資料也可以填寫表中的類中欄位名
publish_obj = models.Publish.objects.filter(pk=1).first()
# models.Book.objects.create(title='水滸傳', price=555.66, publish=publish_obj)
總結:一對一與一對多一致,既可以傳數字也可以傳物件
針對多對多關係繫結
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.add(1) # 在第三張關係表中給當前書籍繫結作者
book_obj.authors.add(2, 3)
book_obj = models.Book.objects.filter(pk=4).first()
author_obj1 = models.Author.objects.filter(pk=1).first()
author_obj2 = models.Author.objects.filter(pk=2).first()
book_obj.authors.add(author_obj1) book_obj.authors.add(author_obj1, author_obj2)
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.set((1, 3)) # 修改關係
book_obj.authors.set([2, ]) # 修改關係
author_obj1 = models.Author.objects.filter(pk=1).first()
author_obj2 = models.Author.objects.filter(pk=2).first()
book_obj.authors.set((author_obj1,)) book_obj.authors.set((author_obj1, author_obj2))
book_obj.authors.remove(2)
book_obj.authors.remove(1, 3) book_obj.authors.remove(author_obj1,) book_obj.authors.remove(author_obj1,author_obj2)
book_obj.authors.clear()
ORM跨表查詢
複習MySQL跨表查詢的思路
子查詢
- 分步操作:將一條SQL語句用括號括起來當做另外一條SQL
語句的條件
連表操作
- 先整合多張表之後基於單表查詢即可
inner join
內連線
left join
左連線
right join
右連線
union
全連線
正反向查詢的概念(重要)
正向查詢
-
由外來鍵欄位所在的表資料查詢關聯的表資料是正向
-
或者說外來鍵在自己手上則是正向查詢
反向查詢
-
沒有外來鍵欄位的表資料查詢關聯的表資料是反向
-
或者說外來鍵在別人手上則是反向查詢
注意:正反向的核心就看外來鍵欄位在不在當前資料所在的表中
ORM跨表查詢的口訣(重要)
-
正向查詢按外來鍵欄位
-
反向查詢按表名小寫
基於物件的跨表查詢
'''基於物件的跨表查詢'''
# 1.查詢主鍵為1的書籍對應的出版社名稱
# 先根據條件獲取資料物件
book_obj = models.Book.objects.filter(pk=1).first()
# 再判斷正反向的概念 由書查出版社 外來鍵欄位在書所在的表中 所以是正向查詢
print(book_obj.publish.name)
# 2.查詢主鍵為4的書籍對應的作者姓名
# 先根據條件獲取資料物件
book_obj = models.Book.objects.filter(pk=4).first()
# 再判斷正反向的概念 由書查作者 外來鍵欄位在書所在的表中 所以是正向查詢
print(book_obj.authors) # app01.Author.None
print(book_obj.authors.all())
print(book_obj.authors.all().values('name'))
# 3.查詢jason的電話號碼
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.author_detail.phone)
# 4.查詢北方出版社出版過的書籍
publish_obj = models.Publish.objects.filter(name='北方出版社').first()
print(publish_obj.book_set) # app01.Book.None
print(publish_obj.book_set.all())
# 5.查詢jason寫過的書籍
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.book_set) # app01.Book.None
print(author_obj.book_set.all())
# 6.查詢電話號碼是110的作者姓名
author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
print(author_detail_obj.author)
print(author_detail_obj.author.name)
基於雙下劃線的跨表查詢
'''基於雙下劃線的跨表查詢'''
# 1.查詢主鍵為1的書籍對應的出版社名稱
res = models.Book.objects.filter(pk=1).values('publish__name','title')
print(res)
# 2.查詢主鍵為4的書籍對應的作者姓名
res = models.Book.objects.filter(pk=4).values('title', 'authors__name')
print(res)
# 3.查詢jason的電話號碼
res = models.Author.objects.filter(name='jason').values('author_detail__phone')
print(res)
# 4.查詢北方出版社出版過的書籍名稱和價格
res = models.Publish.objects.filter(name='北方出版社').values('book__title','book__price','name')
print(res)
# 5.查詢jason寫過的書籍名稱
res = models.Author.objects.filter(name='jason').values('book__title', 'name')
print(res)
# 6.查詢電話號碼是110的作者姓名
res = models.AuthorDetail.objects.filter(phone=110).values('phone', 'author__name')
print(res)
進階操作
'''基於雙下劃線的跨表查詢'''
# 1.查詢主鍵為1的書籍對應的出版社名稱
res = models.Book.objects.filter(pk=1).values('publish__name','title')
print(res)
# 2.查詢主鍵為4的書籍對應的作者姓名
res = models.Book.objects.filter(pk=4).values('title', 'authors__name')
print(res)
# 3.查詢jason的電話號碼
res = models.Author.objects.filter(name='jason').values('author_detail__phone')
print(res)
# 4.查詢北方出版社出版過的書籍名稱和價格
res = models.Publish.objects.filter(name='北方出版社').values('book__title','book__price','name')
print(res)
# 5.查詢jason寫過的書籍名稱
res = models.Author.objects.filter(name='jason').values('book__title', 'name')
print(res)
# 6.查詢電話號碼是110的作者姓名
res = models.AuthorDetail.objects.filter(phone=110).values('phone', 'author__name')
print(res)
'''進階操作'''
# 1.查詢主鍵為1的書籍對應的出版社名稱
res = models.Publish.objects.filter(book__pk=1).values('name')
print(res)
# 2.查詢主鍵為4的書籍對應的作者姓名
res = models.Author.objects.filter(book__pk=4).values('name','book__title')
print(res)
# 3.查詢jason的電話號碼
res = models.AuthorDetail.objects.filter(author__name='jason').values('phone')
print(res)
# 4.查詢北方出版社出版過的書籍名稱和價格
res = models.Book.objects.filter(publish__name='北方出版社').values('title','price')
print(res)
# 5.查詢jason寫過的書籍名稱
res = models.Book.objects.filter(authors__name='jason').values('title')
print(res)
# 6.查詢電話號碼是110的作者姓名
res = models.Author.objects.filter(author_detail__phone=110).values('name')
print(res)
'''補充'''
# 查詢主鍵為4的書籍對應的作者的電話號碼
res = models.Book.objects.filter(pk=4).values('authors__author_detail__phone')
print(res)
res = models.AuthorDetail.objects.filter(author__book__pk=4).values('phone')
print(res)
res = models.Author.objects.filter(book__pk=4).values('author_detail__phone')
print(res)