Upload
ekman-hsieh
View
100
Download
0
Embed Size (px)
Citation preview
➔ 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
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 (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.9 Slicing Data➔ 篩選出前幾筆的資料 (數字不可為負數)
◆ 選出第一筆:Publisher.objects.order_by('name')[0]
◆ 選出前N筆:Publisher.objects.order_by('name')[0:2]
◆ 選出最後一筆:Publisher.objects.order_by('-name')[0]
25