下面將會介紹models的
Fields
Options
Relationships
class Meta
def __str__(self):
每個models的Field分別對應到不同的資料庫欄位型態
這裡會介紹以下幾種Fields,沒介紹的應該用不太到,請自行參考官方文件
文字類型:CharField、TextField、EmailField
整數類型:IntegerField、BigIntegerField、PositiveIntegerField、PositiveSmallIntegerField
小數類型:FloatField、FloatField
日期類型:DateField、DateTimeField
布林類型:BooleanField、NullBooleanField
name = models.CharField(max_length=255)
字元字串欄位,max_length是必要的參數,Django文件建議上限為255,實測結果為長度取決於資料庫上限。
description = models.TextField()
為一個文字框輸入欄位,Django文件建議CharField長度超過255則使用此類型,可以加上max_length參數,但只作用在client端,model及database不起作用。
email = models.EmailField()
電子郵件欄位,若不給參數,預設參數為max_length=254
num = models.IntegerField()
整數類型欄位,值的範圍為-2147483648至2147483647
num = models.BigIntegerField()
64位元整數欄位,值的範圍為-9223372036854775808至9223372036854775807
num = models.PositiveIntegerField()
正整數欄位,值的範圍為0至2147483647
num = models.PositiveSmallIntegerField()
小正整數欄位,值的範圍為0至32767
num = models.FloatField()
浮點數欄位,因為精度問題,在數字計算上可能會有誤差。
models.DecimalField(max_digits=10, decimal_places=3)
十進制欄位,通常使用在計算不可有誤差的地方,如:金額。
需要max_digits及decimal_places這2個參數。
max_digits表示此欄位允許的最大位數
decimal_places表示使用幾個位數顯示小數部分
12345.67有7位數,小數部分2位數
models.DecimalField(max_digits=7, decimal_places=2)
date = models.DateField()
使用python的datetime.date為實例來表示年-月-日
time = models.DateTimeField()
使用python的datetime.datetime為實例來表示年-月-日 時:分:秒
2個日期類型都有auto_now及auto_now_add2個可選參數,預設皆為False。
若設定參數auto_now=True,日期會在資料被新增時自動加入當下的日期時間(新增時指定日期時間無效),新增後只有在每次使用object.save()才會更新日期時間,常常使用在最後編輯的時間。
若設定參數auto_now_add=True,日期會在資料被新增時自動加入當下的日期時間(新增時指定日期時間無效),新增後可隨意修改日期時間,通常用在記錄資料建立的時間。
check = models.BooleanField()
只有true或false的資料型態,預設為false,如果需要接受null,改用NullBooleanField
check = models.NullBooleanField()
接受true、false、null3種資料型態,預設為null,使用此類型,會自動設定null=True參數。
上面介紹的每個Field,除了指定要給的參數為,還有一些參數可供選擇,這裡會介紹以下參數
null
blank
choices
default
help_text
primary_key
unique
verbose_name
name = models.CharField(max_length=10, null=False)
若不指定此參數,預設值為null=False,若設定成null=True,此欄位可允許存入null值。
name = models.CharField(max_length=10, blank=False)
若不指定此參數,預設值為blank=False,若設定成blank=True,此欄位可允許存入空白值。
test
name = models.CharField(max_length=10, default='value')
設定default參數,可指定此欄位預設值為何
default='低否'表示此Char欄位預設值為低否
name = models.CHarField(max_length=20, help_text='This is help text.'
當此欄位使用在form表單時,給予輸入的幫助訊息。
id = models.PositiveIntegerField(primary_key=False)
primary_key參數指定此欄位為table的主鍵,通常不需額外指定此欄位,Django會自動新增一個AutoField型態的id欄位給table當主鍵。
name = models.CHarField(max_length=10, primary_key=True)
如果自行指定其他欄位為primary_key,此欄位會自動增加null=False及unique=True這2個參數。
一張table只允許一個primary_key
phone = models.PositiveIntegerField(unique=False)
unique參數預設為False,如果設定unique=True,表示此欄位所存放的值不可與其他欄位重複。
除了OneToOneField及ManyToManyField之外,其他Field皆可使用此參數。
此參數可以給予欄位一個暱稱來顯示,若不指定此參數,Django會將欄位名稱的字首英文字母大寫,並將底線轉為空格。
下面例子會以First name來顯示
first_name = models.CharField(max_length=10)
下面例子會以Lastname來顯示
last_name = models.CHarField(max_length=10, verbose_name='lastname')
下面例子會以NICK_NAME來顯示,使用此方法,必將顯示名稱放在最前端,才可不輸入verbose_name
nick_name = models.CharField('NICK_NAME', max_length=10)
Django的models也支援了關聯式資料庫的ForeignKey、ManyToOne、OneToOne、ManyTOMany
relation = models.ForeignKey(relate_model_name, on_delete=models.CASCADE)
Django使用ForeignKey來表示ManyToOne關聯,需要給予2個參數:關聯至哪一個model及當關聯的model刪除時要進行的動作。
假設有2張表,1張記錄城市名稱,1張記錄城市居民,關聯如下圖
graph LR
B[Citizen] --> A[City]
C[Citizen] --> A[City]
D[Citizen] --> A[City]
城市的model如下
class City(models.Model)
name = models.CharField(max_length=10)
def __str__(self):
return self.name
居民的model如下
class Citizen(models.Model)
relate_city = models.ForeignKey(City, on_delete=models.CASCADE)
name = models.CharField(max_length=10)
age = models.PositiveIntegerField()
def __str__(self):
return self.name
Citizen的relate_city欄位使用ForeignKey來表示關聯至哪一個model,第一個參數City代表關聯至City這個model,第二個參數on_delete=models.CASCADE代表當關聯的City被刪除時,Citizen也會一起被刪除。
on_delete這個參數有以下幾種用法:
on_delete=models.CASCADE
刪除City時,同時將所有關聯至City的Citizen刪除
on_delete=models.PROTECT
需先將Citizen全部刪除,才可刪除City
on_delete=models.SET_NULL
當City被刪除時,Citizen的relate_city欄位會變成null,需另外設定null=True
on_delete=models.SET_DEFAULT
需另外設定default參數,當所關聯的City被刪除時,自動將此欄位關聯至default指定的關聯表主鍵。
假設今天有下列2張表,Citizen的relate_city設定為relate_city = models.ForeignKey(City, on_delete=models.SET_DEFAULT, default=0)
根據Citizen可得知阿哲住在台北市,阿倫、阿燦住在新北市,阿龍、阿德、阿花住在桃園市。
City|
-----|--------
id(pk)|0|1|2
name|台北市|新北市|桃園市
Citizen| ---|--- id(pk)|0|1|2|3|4|5 relate_city|0|1|1|2|2|2 name|阿哲|阿倫|阿燦|阿龍|阿德|阿花 age|58|57|51|54|58|68
如果把City的桃園市刪除,阿龍、阿德、阿花將無家可歸,還好我們設定了default=0,阿龍、阿德、阿花在桃園市被刪除後,都會搬到台北市居住,變成下表
City|
-----|--------
id|0|1
name|台北市|新北市
Citizen|
---|---
id|0|1|2|3|4|5
relate_city|0|1|1|0|0|0
name|阿哲|阿倫|阿燦|阿龍|阿德|阿花
age|58|57|51|54|58|68
注意,因為台北市被指定為default,所以台北市不可被刪除
on_delete=models.SET()
關聯的資料被刪除時,呼叫SET()內的函式,回傳另外一個關聯物件
例如設定relate_city = models.ForeignKey(City, on_delete=models.SET(get_first_city)
並且有一個函式如下
on_delete=models.DO_NOTHING
relation = models.OneToOneField(relate_model_name, on_delete=models.CASCADE)
資料庫中的一對一關係,與ForeignKey加上unique相似,差別在於反向關係時,OneToOne回傳一個物件,而ForeignKey加上unique會回傳queryset
如果City與Citizen是ForeignKey關係,User與UserProfile是OneToOne關係,程式碼如下:
class City(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Citizen(models.Model):
relate_city = models.ForeignKey(City, on_delete=models.CASCADE)
name = models.CharField(max_length=20)
age = models.PositiveIntegerField()
def __str__(self):
return self.name
class User(models.Model):
uid = models.CharField(max_length=10)
def __str__(self):
return self.uid
class UserProfile(models.Model):
relate_user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=20)
age = models.PositiveIntegerField()
def __str__(self):
return self.name
在command line輸入python manage.py shell進入shell互動模式
>>> from app import models
>>> city = models.City.objects.get(name='Taipei')
>>> citizen = models.Citizen.objects.get(name='ironman')
>>> user = models.User.objects.get(uid='A123456789')
>>> userprofile = models.UserProfile.objects.get(name='superman')
>>> city.citizen_set.all()
<QuerySet [<Citizen: ironman>]>
>>> user.userprofile
<UserProfile: superman>
To be continue...
下方的程式碼會使Test在admin後台以TEST來顯示
class Test(models.Model):
name = models.CharField(max_length=20)
class Meta:
verbose_name = "TEST"
def __str__(self):
return self.name
class Test(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name