26
The Django Book Chapter4 Models 20160524 Django讀書會-ek

Chapter 4 models

Embed Size (px)

Citation preview

The Django BookChapter4 Models

20160524Django讀書會-ek

➔ 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

Model?

➔ Model 是 ”MTV” 設計模式中,用來與資料庫溝通

➔ Django model is a description of the data in your database, represented as Python code.

➔ Database layer / data layout

3

專案的定義: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

➔ This is a project: mysite

➔ This is an app: books

5

4.1 Configuring the Database

➔ Settings.py

參數說明:

1. ENGINE:django.db.backends.sqlite3

2. NAME:your database name

6

4.2 “Dumb” Way

缺點:

1. hard-coding DB connection parameters. → 最好是寫在 config 檔案紀錄重要資訊 (e.g. config.ini)

2. 制式的設定與運算邏輯混雜一起 → 制式的設定應抽離它,讓開發者應專注在邏輯中

3. 使用不同 DB 時,需要重新修改語句 → 用程式抽象化掉底層差異,這樣以後在轉換 DB時,只要專注在

底層實作的改變就好。7

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 的準確度可能會

有差異

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-incrementing interger

9

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

4.5 Installing the Model (cont. sqlmigration)

4. python manage.py sqlmigrate books 0001 可查看其變動的 SQL DDL,尚未真的

對DB做操作

11

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

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

4.5 Installing the Model (cont. migrate)

5. python manage.py migrate 把 Model 變動之處更新於資料庫,此指令才會真的變

動到資料庫。

14

4.6 Basic Data Access

15

➔ python manage.py shell

1. 先 import Model (e.g. Publisher)

➔ (INSERT)新增資料:◆ 兩段式 .save():定義 Publisher object 裡面欄位的值,完成後,記得要 .save(),才會更新。◆ 一段式 .create(...):直接下 Publisher.objects.create(....) ,就會更新。

➔ (SELECT)取得資料:

◆ Publisher.objects.all()

4.6.1 Adding Model String Representations

使用 __str__() ,讓你的 print 結果變美麗:

使用前:

使用後:

➔ 限制: __str__() ,只可回傳字串

16

4.6.2 Inserting and Updating Data - .save()

➔ 新增:

➔ 修改:

17

4.6.2 Inserting and Updating Data (Cont.)

但其實 save() 的 Update 是會把資料整個重新更新,而非只更新差異之處:

真實執行的樣子:

但其實我們只要:

18

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

4.6.4 Selecting Objects

➔ Publisher.objects.all()

◆ SELECT 全部資料,但是不會用 SELECT * 來取資料,而是把欄位名稱皆列出來。

◆ the Zen of Python: “Explicit is better than implicit.”

20

4.6.5 Filtering Data

➔ Publisher.objects.filter(name='Apress')

◆ 多重欄位(AND)預設為 =:Publisher.objects.filter(country="U.S.A.", state_province="CA")

◆ LIKE:Publisher.objects.filter(name__contains="press")

21

4.6.6 Retrieving Single Objects

➔ Publisher.objects.get(name="Apress")

◆ 取出值須為單一資料且不可為空,否則會出錯( Exception)

22

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

4.6.8 Chaining Lookups

➔ 多重條件可串燒在一起:Publisher.objects.filter(country="U.S.A.").order_by("-name")

24

4.6.9 Slicing Data➔ 篩選出前幾筆的資料 (數字不可為負數)

◆ 選出第一筆:Publisher.objects.order_by('name')[0]

◆ 選出前N筆:Publisher.objects.order_by('name')[0:2]

◆ 選出最後一筆:Publisher.objects.order_by('-name')[0]

25

4.6.10 Deleting Objects

➔ 刪除單筆資料:

◆ p = Publisher.objects.get(name="O'Reilly")

◆ p.delete()

◆ Publisher.objects.filter(country='USA').delete()

➔ 全部刪除:

◆ Publisher.objects.all().delete()

26