django框架(部分講解)

吳仁耀發表於2022-12-20

ORM執行SQL語句

有時候ORM的操作效率可能偏低 我們是可以自己編寫SQL的

方式1:
raw()方法執行原生sql語句

models.User.objects.raw('select * from app01_user;')

image

方式2:
直接執行自定義原生sql(完全避開模型層,類似pymysql操作)

from django.db import connection
cursor = connection.cursor()
cursor.execute('select name from app01_user;')
print(cursor.fetchall())

image

神奇的雙下劃線查詢

只要還是queryset物件就可以無限制的點queryset物件的方法

queryset.filter().values().filter().values_list().filter()...

查詢年齡大於18的使用者資料

res = models.User.objects.filter(age__gt=18)
print(res)

image
查詢年齡小於38的使用者資料

res = models.User.objects.filter(age__lt=38)
print(res)

image
大於等於 小於等於

res = models.User.objects.filter(age__gte=18)
res = models.User.objects.filter(age__lte=38)

image
查詢年齡是18或者28或者38的資料

res = models.User.objects.filter(age__in=(18, 28, 38))
print(res)

image

查詢年齡在18到38範圍之內的資料

res = models.User.objects.filter(age__range=(18, 38))
print(res)

image
查詢名字中含有字母j的資料
區分大小寫

res = models.User.objects.filter(name__contains='j')
print(res)

image
不區分大小寫

res = models.User.objects.filter(name__icontains='j')
print(res)

image
查詢註冊年份是2022的資料

res = models.User.objects.filter(register_time__year=2022)
print(res)

image
針對django框架的時區問題 是需要配置檔案中修改的 後續bbs講解

ORM外來鍵欄位的建立

複習MySQL外來鍵關係

一對多
外來鍵欄位建在多的一方
多對多
外來鍵欄位統一建在第三張關係表
一對一
建在任何一方都可以 但是建議建在查詢頻率較高的表中
總結:關係的判斷可以採用換位思考原則

ORM外來鍵欄位建立

第一步:建立庫修改配置檔案連線資料庫
image
第二步:建立基礎表(書籍表、出版社表、作者表、作者詳情)
image
第三步:確定外來鍵關係
image

一對多 ORM與MySQL一致 外來鍵欄位建在多的一方
image
多對多 ORM比MySQL有更多變化

  1. 外來鍵欄位可以直接建在某張表中(查詢頻率較高的)
    內部會自動幫你建立第三張關係表
  2. 自己建立第三張關係表並建立外來鍵欄位
    一對一 ORM與MySQL一致 外來鍵欄位建在查詢較高的一方
    image
    執行遷移命令連線資料庫
    image
    image

第四步:ORM建立
針對一對多和一對一同步到表中之後會自動加_id的字尾
image

publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)

針對多對多 不會在表中有展示 而是建立第三張表

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

image

外來鍵欄位相關操作

前期準備(給表錄入一些資料)
image

image

image
針對一對多 插入資料可以直接填寫表中的實際欄位

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)

相關文章