Django外來鍵關係描述
注:本文需要你有一定的資料庫知識,本文的資料庫語法使用mysql書寫
Django中,跟外來鍵有關的關係有三種,下面來一一介紹。
OneToManyField
這種最好理解,說白了就是最普通的外來鍵,看看下面兩個模型:
class GoodsType(models.Model):
name = models.CharField(max_length=50)
class GoodsMessage(models.Model):
Title = models.CharField(max_length='100') # 商品標題
Category = models.ManyToManyField(GoodsType) # 商品標籤
分析一下:
這裡Django會在資料庫中創兩張表:
create table GoodsType(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
)
create table GoodsMessage(
`id` int(11) NOT NULL AUTO_INCREMENT,
`Title` varchar(50) NOT NULL,
`Category_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`Category_id`) REFERENCES `SchoolBuy_goodstype` (`id`)
)
這樣的結果就是一個商品會對應一個類別,即類別是商品的外來鍵。
OneToOneField
這種關係和OneToMany類似,是一種有約束的外來鍵,看看下面兩個模型:
class GoodsType(models.Model):
name = models.CharField(max_length=50)
class GoodsMessage(models.Model):
Title = models.CharField(max_length='100' ) # 商品標題
Category = models.OneToManyField(GoodsType) # 商品標籤 (變為一對一關係)
他們會使得資料庫建立什麼表呢?
create table GoodsType(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
)
create table GoodsMessage(
`id` int(11) NOT NULL AUTO_INCREMENT,
`Title` varchar(50) NOT NULL,
`Category_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`Category_id`) REFERENCES `SchoolBuy_goodstype` (`id`),
UNIQUE KEY `SchoolBuy_goodsmessage_Category_id_4dd415fc1e19cf24_uniq` (`Category_id`) # 新增
)
那麼這裡已經很明顯了,在這兩個模型裡,每個商品有一個商品型別,並且每個商品型別只屬於一個商品(用了UNIQUE
約束),即如果我A商品的型別是電腦
,那麼其他商品的型別都不能定義為電腦
了。
所以商品與型別的對應關係肯定不能是OneToOne,而應該是OneToMany。
那麼OneToOne用在哪裡呢?這裡說一個地方,在擴充套件Django的User模型時,因為系統自帶的欄位不夠,所以一種最基本的擴充套件方法是定義一個User_profile表,用來作為使用者的擴充套件,那麼一條使用者記錄只會有一個擴充套件表記錄,並且這個這個記錄也只屬於該使用者。
ManyToMany
多對多關係,這裡我們假設一種情景:
我現在有一個商品表,這個商品有一些圖片(不定數量),那麼可以使用多對多關係:
class GoodsPicture(models.Model):
Pic = models.ImageField(upload_to='pic/')
class GoodsMessage(models.Model):
Title = models.CharField(max_length='100') # 商品標題
Pic = models.ManyToManyField(GoodsPicture)
這裡資料庫不同啦,建立了三張表,具體如下:
create table GoodsPicture(
`id` int(11) NOT NULL AUTO_INCREMENT,
`Pic` varchar(255) NOT NULL, # Django對於圖片的儲存採用的是二進位制圖片檔案存硬碟,資料庫只儲存圖片路徑
PRIMARY KEY (`id`)
)
create table GoodsMessage(
`id` int(11) NOT NULL AUTO_INCREMENT,
`Title` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
# 注意了,這裡沒有外來鍵約束了
)
create table GoodsMessage_CoodsPicture(
`id` int(11) NOT NULL AUTO_INCREMENT,
`goodsmessage_id` int(11) NOT NULL,
`goodpicture_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `goodsmessage_id` (`goodsmessage_id`,`goodspicture_id`),
FOREIGN KEY (`goodsmessage_id`) REFERENCES `GoodsMessage` (`id`),
FOREIGN KEY (`goodstype_id`) REFERENCES `GoodsPicture` (`id`)
)
前兩個表就不講了,主要說一下第三個表GoodsMessage_CoodsPicture,
Django用這個表來記錄一條資料,內容為:某個商品對應某張圖片。其中有一個UNIQUE
約束,說明不能有重複的記錄。
這樣,每次查詢GoodsMessage_CoodsPicture表,就能獲得某件商品對應的圖片。
這裡講了他們在資料庫中的實現,那麼Django如何來查詢這些資料呢,有一篇好的博文推薦給大家:
Django ORM、一對一、一對多、多對多、詳解