2. ➔ Model?
➔ 專案的定義:project vs app
➔ 4.1 Configuring the Database
➔ 4.2 “Dumb” Way
➔ 4.3 Defining Models in Python
➔ 4.4 Our First Model
➔ 4.5 Installing the Model
We'll go through
2
➔ 4.6 Basic Data Access
◆ 4.6.1 Adding Model String Representations
◆ 4.6.2 Inserting and Updating Data
◆ 4.6.3 Updating Multiple Objects in One Statement
◆ 4.6.4 Selecting Objects
◆ 4.6.5 Filtering Data
◆ 4.6.6 Retrieving Single Objects
◆ 4.6.7 Ordering Data
◆ 4.6.8 Chaining Lookups
◆ 4.6.9 Slicing Data
◆ 4.6.10 Deleting Objects
3. Model?
➔ Model 是 ”MTV” 設計模式中,用來與資料庫溝通
➔ Django model is a description of the data in your database, represented as
Python code.
➔ Database layer / data layout
3
4. 專案的定義:project vs app
➔ python manage.py startproject | startapp
Project is an instance of a certain set of Django apps, plus the configuration for
those apps. (Project = Django app + app config)
App is a portable set of Django functionality, usually including models and views,
that lives together in a single Python package.
而當我們要開始使用 Database layer (models) 時,我們必須建立 Django app.
➔ Models must live within apps.
4
5. ➔ This is a project: mysite
➔ This is an app: books
5
6. 4.1 Configuring the Database
➔ Settings.py
參數說明:
1. ENGINE:django.db.backends.sqlite3
2. NAME:your database name
6
7. 4.2 “Dumb” Way
缺點:
1. hard-coding DB connection parameters. → 最好是寫在 config 檔案紀錄重要資訊 (e.g. config.ini)
2. 制式的設定與運算邏輯混雜一起 → 制式的設定應抽離它,讓開發者應專注在邏輯中
3. 使用不同 DB 時,需要重新修改語句 → 用程式抽象化掉底層差異,這樣以後在轉換 DB時,只要專注在
底層實作的改變就好。
7
8. 4.3 Defining Models in Python
➔ Python code / data layout
優點:
1. 單一語言讓開發者專注於商業邏輯,而非語言(“context
switch.”)
2. 把 Model 當成程式,一起進版控(Version Control)
3. 不局限於SQL的處理範圍,可以處理更複雜化的
higher-level concepts/data types (ex: email, URL)
4. 在 distribute Web 應用時,Model 會比 SQL statement
更實用(pragmatic)
缺點:
1. Model修改時,不能即時同步到資料庫,須使用
mıgratıon 指令
8
➔ Introspect database at runtime
優點:
1. 對DB來說較直覺....
缺點:
1. 作者認為不符合Django開發者的期待(Django’s
developers aim to trim as much framework
overhead as possible.)
2. 資料庫版本之間,對於 metadata 的準確度可能會
有差異
9. 4.4 Our First Model - book/author/publisher data layout #models.py
➔ 使用 django.db.models.Model 模組
➔ 每一個 model class 對應到一個資料表
➔ class 中的 attribute 對應到資料表內的欄位
➔ field的類型(e.g., CharField) 對應的是資料表的欄位
限制(e.g., varchar).
例外:多對多的關係會是 one-class-per-database-table rule
的例外 (ex: Book has a ManyToManyField called
authors.),Django creates an additional table – a many-to-
many “join table”
➔ 每個 model 都需要有一個 Primary key 的欄位
➔ 預設 model 會自動生成一個 id 欄位,值為 auto- 9
10. 1. 把 'books' model 加到 settings.py 的 INSTALLED_APPS
列表中
2. python manage.py check 用來驗證 models code 是否有錯
3. python manage.py makemigrations books DB schma 有變
動時,此指令會把變動資料存成檔案放在 ./migrations 資料
夾下
4.5 Installing the Model
10
# books refers to the books app
11. 4.5 Installing the Model (cont. sqlmigration)
4. python manage.py sqlmigrate books 0001 可查看其變動的 SQL DDL,尚未真的
對DB做操作
11
12. 4.5 Installing the Model (cont. sqlmigration)
➔ 命名規則:(詳見Appendix B.)
◆ Model name: Publisher, Book, Author
◆ App name: books
◆ Table name: books_publisher, books_book, books_author
➔ Foreign key:
◆ 會使用 REFERENCES 來建置
◆ By convention, Django appends "_id" to the foreign key field name
12
13. 4.5 Installing the Model (cont. sqlmigration)
➔ 好處:
◆ 針對不同資料庫的 syntax 自動作轉換。(database-specific field types such as auto_increment
(MySQL), serial (PostgreSQL), or integer primary key (SQLite) are handled for you.)
automatically.
◆ 處理掉單引號與雙引號。 (quoting of column names (e.g., using double quotes or single quotes).
)
13
14. 4.5 Installing the Model (cont. migrate)
5. python manage.py migrate 把 Model 變動之處更新於資料庫,此指令才會真的變
動到資料庫。
14
18. 4.6.2 Inserting and Updating Data (Cont.)
但其實 save() 的 Update 是會把資料整個重新更新,而非只更新差異之處:
真實執行的樣子:
但其實我們只要:
18
19. 4.6.3 Updating Multiple Objects in One Statemen
➔ 更新特定欄位: {QuerySet}.update(...)
◆ 更新單一筆的欄位: Publisher.objects.filter(id=52).update(name='Apress Publishing')
◆ 更新多筆的欄位 Publisher.objects.all().update(country='USA')
19
20. 4.6.4 Selecting Objects
➔ Publisher.objects.all()
◆ SELECT 全部資料,但是不會用 SELECT * 來取資料,而是把欄位名稱皆列出來。
◆ the Zen of Python: “Explicit is better than implicit.”
20
23. 4.6.7 Ordering Data
➔ Publisher.objects.order_by("name")
◆ 多重欄位:Publisher.objects.order_by("state_province", "address")
◆ 順序反向:Publisher.objects.order_by("-name")
◆ Model 內使用 class Meta 直接定義
23