先來看一下相關名詞的對應:
在ORM中,類別相當於資料庫裡的表,物件則是指每列紀錄,屬性則是各字段。
在Django中,我們建立一個新的app時,產生的資料夾內會有一個model.py檔,這個檔案預設就是要讓我們來建立ORM Class用的。
在model.py裡要寫的是像底下這樣的程式碼:
from django.db import models
class Greeting(models.Model):
name = models.CharField(max_length=50)
message = models.CharField(max_length=200)
timestamp = models.DateField(auto_now=True)
...
class Meta:
db_table = ...
...
在上例,就像是建立了一個叫做app_greeting的表 ( [應用名_類別名] ),表裡有name、message、timestamp這三個欄位。
Meta類別:
每個繼承自 django.db.models.Model類別都有Meta子類別,可定義模型中繼資料,例如資料表名、資料預設排序方式等。
屬性
|
解釋
|
db_table
|
表名
|
ordering
|
設定預設排序欄位,可設定多個欄位,預設為升冪,降冪排序在欄位名前面加負號就可
|
verbose_name
|
表的別名備註
|
verbose_name_plural
|
Verbose name複數
|
abstract
|
是否為抽象類別
|
permissions
|
設置額外權限用,2-tuples (permission_code,
human_readable_permission_name)
|
managed
|
定義manage.py命令列工具是否管理本模型 (預設是True)
|
unique_together
|
用來設定不重複的欄位組合
|
app_label
|
定義本類別所屬的應用
|
db_tablespace
|
對應表格空間名稱,表格空間的概念只存在在某些資料庫中,如Oracle
|
欄位類型:
欄位類型
|
解釋
|
AutoField
|
自動遞增的整數欄位,通常用作資料表的主鍵。
|
BigAutoField
|
同AutoField,但能容更大的值(64-bit)
|
BooleanField
|
布林值(預設值是None)
|
PositiveSmallIntegerField
|
0 ~ 32767
|
SmallIntegerField
|
-32768 ~ 32767
|
PositiveIntegerField
|
0 ~ 2147483647
|
IntegerField
|
-2147483648 ~ 2147483647
|
BigIntegerField
|
-9223372036854775808 ~
9223372036854775807
|
CharField
|
相當於varchar (使用max_length指定最大長度)
|
TextField
|
相當於longtext
|
DateField
|
年月日 (auto_now_add:當物件第一次被建立時將該欄位的值設定為目前時間;auto_now:當物件被儲存時將該欄位的值設定為目前時間)
|
DateTimeField
|
年月日時分秒
|
DurationField
|
一段時間 (int, 用Python的timedelta類型建置)
|
FloatField
|
浮點數欄位
|
DecimalField
|
表示小數用,需導入參數max_digits:總位數(不含小數點和符號)、decimal_places:小數位數
|
EmailField
|
帶有檢查Email合法性的CharField
|
ImageField
|
類似FileField,同時驗證上船物件是否是一個合法圖片。設定height_field、width_field將會按此高度寬度規格來存圖片
|
FileField
|
檔案上傳欄位,upload_to可指定上傳路徑
|
FilePathField
|
檔案路徑欄位
|
URLField
|
儲存URL
|
UUIDField
|
儲存UUID
|
GenericIPAddressField
|
IPv4或IPv6 address
|
欄位參數:
- 所有字段都具有的參數:
參數
|
解釋
|
db_column
|
重新為欄位命名
|
primary_key
|
是否為主鍵
|
verbose_name
|
字段的別名或備註
|
unique
|
字段值在表中必須唯一
|
null
|
資料庫中可否為空
|
blank
|
表單欄位可否為空 (blank=True時null也一定要為True)
|
db_index
|
設定為索引參數
|
help_text
|
在表單中顯示幫助訊息
|
editable
|
用戶可否編輯 (該field不會出現在admin或任何ModelForm)
|
- 關係型字段的參數:
1. related_name:主物件找到副物件的別名。
# Account和Contact是1:N關係
# 在Contact中有 account = models.ForeignKey(Account)
a1 = Account(user="Rose")
c1 = Contact(account = a1, mobile="1234")
print(a1.contact_set) # 預設會是 xxx_set,若在Contact設定裡加入relate_name="yyy",則可以就用a1.yyy就行
2. on_delete:表示當關聯模型被刪除時要做什麼動作
有六種設定:
(1) models.CASCADE:一起刪除
(2) models.PROTECT:阻止刪除,並報 ProtectedError
(3) models.SET_NULL:設置成null (此欄要為null=True, blank=True)
(4) models.DEFAULT:設置成default值 (此欄要有 default=?)
(5) models.DO_NOTHING:什麼也不做
(6) models.SET:自定義一個對應的實體
表格的關係操作:
1. one-to-one:models.OneToOneField()2. foreign key (one-to-many):models.ForeignKey()
3. many-to-many:models.ManyToManyField()
範例:
1. 老師與助教 (1:1):
class Teacher(models.Model):
name = models.CharField(max_length=30, db_index=True)
intro = models.CharField(max_length=300, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="創建時間")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新時間")
class TeacherAssistant(models.Model):
name = models.CharField(max_length=30, db_index=True)
teacher = models.OneToOneField(Teacher, null=True, blank=True, on_delete=models.SET_NULL)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="創建時間")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新時間")
2. 老師與課程 (1:N):
class Course(models.Model):
title = models.CharField(max_length=50, db_index=True)
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="創建時間")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新時間")
3. 課程與學生 (M:N):
class Student(models.Model):
name = models.CharField(max_length=30, db_index=True)
course = models.ManyToManyField(Course)
gender= models.CharField(choices=((1,"男"), (2, "女"), (0, "保密")), max_length=1, default=0)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="創建時間")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新時間")
參考資料:
1. 一次搞定:所有Python Web框架開發百科全書
沒有留言:
張貼留言