Django 中的模型
模型是所有 ORM 的核心。 模型代表應用程式所要使用的一些資料。 這些資料可以是應用程式所需的人員、產品、類別,或是任何其他形式的資料。
建立模型
在 Django 中,所有從 django.models.Model
繼承功能集合的類別,都稱為模型。 此集合包含各種方法,可讓您查詢資料庫、建立新項目,以及儲存更新。 您也可以定義欄位、設定中繼資料,以及建立模型之間的關聯性。
您若想要建立兩個模型 (Product
與 Category
),必須新增兩個類別:
from django.db import models
class Product(models.Model):
# details would go here
pass
class Category(models.Model):
# details would go here
pass
新增方法
在討論如何設定模型的資料之前,必須先強調模型屬於 Python 類別。 因此,您可以同時新增方法及覆寫 Django.models.Model
所提供的方法,或所有 Python 物件固有的方法。
有一個需要特別強調的方法是 __str__
。 當未指定任何欄位時,您可以使用此方法來顯示物件。 若 Product
有一個 name
欄位 (等下就會看到),您可以藉由覆寫 __str__
,以 Product
的預設字串表示法傳回該欄位。
class Product(models.Model):
name = models.TextField()
def __str__(self):
return self.name
新增欄位
欄位定義了模型的資料結構。 欄位可能包含項目的名稱、建立日期、價格,或其他任何模型需要儲存的資料片段。
不同的資料片段具有不同的資料類型、驗證規則及其他格式的中繼資料。 Django ORM 提供一組豐富的選項,可讓您依照自己的指定來設定模型的欄位。 ORM 可以擴充,因此您可以視需要建立自己的規則。
定義欄位類型
所有欄位的核心中繼資料,都是需要儲存的資料類型,例如字串或數字。 欄位類型會同時對應至資料庫類型與 HTML 表單控制項類型 (例如文字方塊或核取方塊)。 Django 包含幾種欄位類型 \(英文\),包括:
CharField
:單行文字。TextField
:多行文字。BooleanField
:布林值 true/false 選項。DateField
:日期。TimeField
:時間。DateTimeField
:日期與時間。URLField
:URL。IntegerField
:整數。DecimalField
:固定有效位數的十進位數。
若要將欄位新增至我們的 Product
與 Category
類別,我們的程式碼將會如下所示:
from django.db import models
class Product(models.Model):
name = models.TextField()
price = models.DecimalField()
creation_date = models.DateField()
class Category(models.Model):
name = models.TextField()
欄位選項
您可以使用欄位選項 \(英文\),新增中繼資料來允許 null 或空白值,或將欄位標示為不得重複。 您也可以設定驗證選項,以及為驗證錯誤提供自訂訊息。
一如欄位類型,欄位選項會對應到資料庫中適當的設定。 這些規則會在 Django 代您產生的所有表單中施行。
欄位選項會傳遞給欄位本身的函式。 不同的欄位可能支援不同的選項。 一些最常見的選項包括:
null
- 允許 null 值的布林值選項。
- 預設值為
False
。
blank
- 允許空白值的布林值選項。
- 預設值為
False
。
default
- 若未提供欄位的值,將會允許設定預設值。
- 若要將預設值設定為資料庫
null
,請將default
設定為None
。
unique
- 此欄位的值不得重複。
- 預設值為
False
。
min_length
和max_length
- 搭配字串類型使用,可識別字串的最短與最長長度。
- 預設值為
None
。
min_value
和max_value
- 搭配數字類型使用,可識別最小值與最大值。
auto_now
和auto_now_add
。- 搭配日期/時間類型使用,可指定是否應使用目前的時間。
auto_now
「一律」會將欄位設定為儲存當時的時間,這對last_update
欄位而言很有幫助。auto_now_add
會將欄位設定為建立當時的時間,這對creation_date
欄位而言很有幫助。
注意
儘管值 null
與 blank
看起來很相似,但在資料庫字詞中卻是表示不同的事物。 null
表示缺少值,blank
特別指空白值。
若要在模型中新增選項,程式碼可能如下所示:
from django.db import models
class Product(models.Model):
name = models.TextField(max_length=50, min_length=3, unique=True)
price = models.DecimalField(min_value=0.99, max_value=1000)
creation_date = models.DateField(auto_now_add=True)
class Category(models.Model):
name = models.TextField(max_length=50, min_length=3, unique=True)
索引鍵與關聯性
關聯式資料庫中的標準做法,是為資料表中的每個資料列設定主索引鍵,而這通常是自動遞增的整數。 Django 的 ORM 會藉由新增名為 id
的欄位,自動將此索引鍵新增至您建立的每個模型。
若您想要覆寫此行為,可以將您想要的欄位設定為您的主索引鍵。 在大部分情況下,您應該使用 Django 的 id
欄位。
關聯式資料庫的資料表之間也有關聯性。 產品有類別,員工有經理,汽車有製造商。 Django 的 ORM 可以支援您想要在模型之間建立的各種關聯性。
「一對多」是最常見的關聯性,技術名詞稱為「外部索引鍵關聯性」。 在外部索引鍵關聯性中,多個項目會共用同一個屬性。 例如將多項產品分組成同一類別。 若要建構此關聯性,必須使用 ForeignKey
欄位。
若要建立關聯性,必須將 ForeignKey
欄位新增至子物件。 若您將產品分為不同類別,可以將 category
屬性新增至 Product
類別,並將類型設定為 ForeignKey
。
Django 會自動將屬性新增至父系,以提供所有稱為 <child>_set
之子系的存取權,其中 <child>
是子物件的名稱。 在我們的範例中,Category
會自動新增 product_set
,以提供類別中所有產品的存取權。
ForeignKey
有一個必要參數:on_delete
\(英文\)。 此參數會告訴 Django 當父系刪除時所應採取的動作。 意即,若我們刪除了類別,該類別中的產品應如何?
最常見的兩個選項如下:
CASCADE
:若我們的範例中有類別刪除,將會刪除所有產品。PROTECT
:若我們嘗試刪除內含產品的類別,將會傳回錯誤。
注意
在大多數情況下,您會想要使用 PROTECT
。
若要更新我們的模型來建立關聯性,可以使用下列程式碼:
from django.db import models
class Product(models.Model):
name = models.TextField()
price = models.DecimalField()
creation_date = models.DateField()
category = models.ForeignKey(
'Category', #The name of the model
on_delete=models.PROTECT
)
class Category(models.Model):
name = models.TextField()
# product_set will be automatically created