iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 7
0
自我挑戰組

零基礎成為 AI 解夢大師秘笈系列 第 7

【零基礎成為 AI 解夢大師秘笈】Day07 - Django IV

  • 分享至 

  • xImage
  •  

斜槓學習 – 零基礎成為 AI 解夢大師秘笈

前言

系列文章簡介

大家好,我們是 AI . FREE Team - 人工智慧自由團隊,這一次的鐵人賽,自由團隊將從0到1 手把手教各位讀者學會 (1)Python基礎語法 (2)Python Web 網頁開發框架 – Django (3)Python網頁爬蟲 – 周易解夢網 (4)Tensorflow AI語言模型基礎與訓練 – LSTM (5)實際部屬AI解夢模型到Web框架上。

為什麼技術要從零開始寫起

自由團隊的成立宗旨為開發AI/新科技的學習資源,提供各領域的學習者能夠跨域學習資料科學,並透過自主學習發展協槓職涯,結合智能應用到各式領域,無論是文、法、商、管、醫領域的朋友,都可以自由的學習AI技術。

資源

AI . FREE Team 讀者專屬福利 → Python Basics 免費學習資源

今日目標

  • Django Shell Command - 利用指令來操作資料庫

教學開始

我們昨天在最後一部分已經將「古人查詢系統」的兩個 model 設計出來了,在今天,我們會看看有什麼簡單的方式可以對資料庫做新增(Create)、刪除(Delete)、修改(Update)、查看(Read)的動作。我們在今天會先使用 Shell Command的方式做到上方提到的動作,在未來幾篇會陸續提到其他種可以達到相同目的的方法,敬請期待!

1 Django Shell Command

在 Django 內,有很多已經被設計好可以用來呼叫資料庫裡面 data 的方法了,我們可以直接的在 Django Shell 裡面進行操作,要進入 Shell Command 會需要使用到 manage.py,所以在一開始,我們就先切換路徑至 .../DI_project(這樣才能和 manage.py 同一層目錄),然後透過 manage.py 進入 shell 介面。
Note: Shell 翻譯成中文是「殼層」的意思,其實就是一個便於大家使用特定功能的介面。

$ cd DI_project
$ python manage.py shell

大家應該會看到類似下面的介面(有沒有覺得和輸入 python 後顯示的介面很像呢)

Python 3.7.4 (default, Aug  9 2019, 18:34:13) [MSC v.1915 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>

我們接著就要在 >>> 後方輸入我們的 Command 指令了。在下方將會使用 Djagno 的 Shell Command 做到增、刪、改、查的動作。其實可以把 Shell 當作是一個小小的實驗室,我們能先在這邊測試想法是否正確且符合預期,確定沒問題之後再將對應的 Command 加入專案的程式裡頭。

2 事前準備 -- import

$ from demo_app.models import Ancient_People, School

在這邊又再次複習 import package 的觀念了,在 DI_project/models.py 裡面是兩個我們昨天寫好的 model(在 python 當中被視為 class),一個是 Ancient_People,另一個則是 School,因為我們等等是要對這兩個 model 做一些操作,所以在這邊要先 import 起來。

因為下面會使用到昨天提到的資料,所以我們再一次把表格列出來,等等大家就可以邊打邊copy,應該會比較快一些!(這邊順便附上英文,英文的程式相容性總是比中文高,所以之後我們都會用英文喔。)

古人(name) 名言(statement) 歲數(age)
孔子(Confucius) 有朋自遠方來,不亦樂乎? 見利思義,見危受命。(Is it not delightful to have friends coming from distant quarters? ...) 27
孟子(Mencius) 獨樂樂,與人樂樂,孰樂?(A single person's joy will never measure up to the joy shared by all.) 65
荀子(Xunzi) 鍥而舍之,朽木不折;鍥而不捨,金石可鏤。(Carving something but giving up halfway, we cannot even carve rotten wood. ...) 67
老子(Lao Tzu) 治大國,若烹小鮮。(Ruling a large nation is like cooking a small delicacy.) 18
莊子(Zhuangzi) 真者,精誠之志也,不精不誠,不能動人。(The true, sincere to the same, not fine and sincere, can not move.) 22
學派(school_name) 中心價值(core_value) 全盛時期人數(num_member)
道家(Taoism) 人與自然的和諧相處。(Harmony between man and nature.) 4777
儒家(Confucianism) 人與人之間要「仁」與「禮」。(Benevolence and courtesy between people.) 3952

全部都列出來之後發現自己好像在傳教(笑)

3 新增(增) 與 讀取(查)

大家先確定自己有在Django Shell 裡面,而且已經有 import 兩個 models 了。準備好之後,我們先看看目前擁有的資料,在我們都還沒有加入的情況下,預計什麼都沒有。

>>> School.objects.all()
<QuerySet []>

回傳的 schools 是一個空的 QuerySet,符合我們的預期。我們接著加入道家的資料

>>> School.objects.create(school_name="Taoism", core_value="Harmony between man and nature.", num_member=4777)
<School: School object (1)>

這邊的 School 是在上方我們 import 進來的其中一個 model,而在 create 這個方法裡面,我們需要各別提供一個值最初在設計 model 的時候設計的 Field,像是「把”Taoism” 這個值 給 school_name 這個 Field」、「把 4777 這個值 給 num_member 這個 Field」。這邊如果大家有點疑惑的,就把 models.py 打開好好研究一番吧!

回傳的 School object,其中的 1 表示它的 id 是 ,並不是目前一共有1筆資料喔。如果我在新增這個 School Object 之前有建立5筆資料,然後再刪掉的話,這邊會出現的數字就會是6了,所以注意一下,這邊的數字表示是 id,不是共有幾筆資料。總之,我們也把另一個學派(儒家)也加進資料庫吧。

>>> School.objects.create(school_name="Confucianism", core_value="Benevolence and courtesy between people.", num_member=3952)
<School: School object (2)>
>>> School.objects.all()
<QuerySet [<School: School object (1)>, <School: School object (2)>]>

在新增了儒家的資料之後再次查看目前有的所有 School Object,確實只有剛剛加的兩筆。不過這邊有個地方可以稍微修改一下,我們發現回傳的兩個 School Object 並不直觀,我們希望他可以回傳兩個字串,先退出 Django Shell Command 介面。

$ exit()

4 修改 models.py 的回傳方式

我們開啟 demo_app/ models.py 並在每個 class 最下方加入一個 def,目的就是希望 queryset 可以回傳直觀的內容,也就是該古人的名字(name),或是該學派的名字(school_name)。

from django.db import models
 
class School(models.Model):
    # 學派名稱
    school_name = models.CharField(max_length=10)
    # 中心價值
    core_value = models.CharField(max_length=100)
    # 人數
    num_member = models.IntegerField()
 
    def __str__(self):
        return self.school_name
 
class Ancient_People(models.Model):
    # 學派
    school = models.ForeignKey(School, on_delete=models.CASCADE)
    # 名字
    name = models.CharField(max_length=10)
    # 名言
    statement = models.CharField(max_length=100)
    # 歲數
    age = models.IntegerField()
 
    def __str__(self):
        return self.name

這邊用到 self,大家應該沒有很陌生吧,如果 function (ex: def __str__) 想要 accessclass (ex: Ancient_People) 內的變數,就需要用 self 去找到 class 內部的變數喔。

5 新增(增) 與 讀取(查)

每一次進入 shell 都需要重新 import 一次 models,但資料的部分還是會保留著,不過因為我們剛剛有去多加兩個 def,所以回傳的值就會不太一樣了。

>>> from demo_app.models import School, Ancient_People
>>> School.objects.all()
<QuerySet [<School: Taoism>, <School: Confucianism>]>

我們在這邊看到的 Taoism 和 Confucianism,是不是就比 School Object (1) 和 (2) 直觀許多了呢!

到現在,我們都還沒有建立針對 Ancient_People 的資料,我們馬上來按照上面的方式加加看。會出錯。

>>> Ancient_People.objects.create(name="Confucius", statement="Is it not delightful to have friends coming from distant quarters? ...", age=27)
.
.
sqlite3.IntegrityError: NOT NULL constraint failed: demo_app_ancient_people.school_id

此時會有錯誤,會發生這個錯誤是因為我們有在 Ancient_People 添加一行關於 Foreign Key 的設定,School 和 Ancient_People 之間是有依存關係的。在目前的設定而言,Ancient_Peolple 在被建立時會需要加入已經存在的 School Object,所以我們要換一種方式建立 Ancient_People 的資料。

我們先透過 get 的方式將儒家(Confucianism)資料取出(因為孔子是儒家學派的),並 assign 給一個變數(demo1, demo2, ...)。

>>> demo1 = School.objects.get(school_name="Confucianism")
>>> demo2 = School.objects.get(core_value="Benevolence and courtesy between people.")
>>> demo3 = School.objects.get(num_member=3952)
>>> demo4 = School.objects.get(id=2)
>>> demo1 # demo2, demo3, demo4 都會回傳一樣的東西
<School: Confucianism>

然後再利用這個透過 get 得到的儒家 School Object 去添加 Ancient_People 的資料。

>>> demo1.ancient_people_set.create(name="Confucius", statement="Is it not delightful to have friends coming from distant quarters? ...", age=27)
<Ancient_People: Confucius>
>>> Ancient_People.objects.all()
<QuerySet [<Ancient_People: Confucius>]>

注意到我們在 demo1 後面是使用 ancient_people_set ,ancient_people 是 class 名稱的小寫版本(i.e. class 名稱是 Ancient_People,是大寫的),這個是在我們給定 ForeignKey 的時候就被 Django 預設好的,而 _set也,表示 Django 預想到 demo1 這個 School Object 應該要有好幾個 Ancient_People。實際上的確也符合我們的使用情境,儒家(School)確實有好幾個古人(Ancient_People)在裡面。

大家接著可以順便也把道家的資料建立起來,然後再接著補進老子和莊子的資料。

6 修改

假設我們想要修改道家的中心思想,將最後的標點符號改成驚嘆號(!),那該怎麼做呢?

>>> Taoism = School.objects.get(school_name="Taoism")
>>> Taoism.core_value
'Harmony between man and nature.' # 原本是句號
>>> Taoism.core_value = 'Harmony between man and nature!' #改成驚嘆號
>>> Taoism.save() # 儲存更動
>>> test_result = School.objects.get(school_name="Taoism")
>>> test_result.core_value
'Harmony between man and nature!' #真的有變成驚嘆號

相當好理解,我們一樣會需要先 get 到目標 object 然後 assign 給一個變數(i.e. Taoism),接著我們可以直接在 . 後面加上 Field (i.e. core_value) 來做到觀看值和更動值的行為。

7 刪除

在這邊就只要先 get 到,然後 delete 就完事了。延續使用上方(修改)最後用到的 test_result。

>>> test_result.delete()
(1, {'demo_app.School': 1})
>>> School.objects.all()
<QuerySet [<School: Confucianism>]>

這個時候,若再去觀察 School Object 會發現其回傳值會變少一筆。

8 邁向 AI 解夢大師 - 第七天

在觀看明天的內容前,想先請大家將2個學派,5個古人都加到資料庫裡面,大家可以順便當作複習,這些資料在明天會使用到喔!

我們今天使用了 Django Shell Command 對資料庫做了增刪改查的行為,其實在這篇文章提到的也只是一部分的指令而已,如果大家還想要看看有什麼其他方式可以做到查詢,推薦可以點進參考連結喔! 在明天,我們會去調整 view.py 的設計,讓網頁呈現出資料庫內有的資料。

9 參考連結

想更深入認識 AI . FREE Team ?

自由團隊 官方網站:https://aifreeblog.herokuapp.com/
自由團隊 Github:https://github.com/AI-FREE-Team/
自由團隊 粉絲專頁:https://www.facebook.com/AI.Free.Team/
自由團隊 IG:https://www.instagram.com/aifreeteam/
自由團隊 Youtube:https://www.youtube.com/channel/UCjw6Kuw3kwM_il39NTBJVTg/

文章同步發布於:自由團隊部落格
(想看更多文章?學習更多AI知識?敬請鎖定自由團隊的頻道!)


上一篇
【零基礎成為 AI 解夢大師秘笈】Day06 - Django III
下一篇
【零基礎成為 AI 解夢大師秘笈】Day08 - Django V
系列文
零基礎成為 AI 解夢大師秘笈30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言