1. 程式人生 > >Django外來鍵關係描述

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、一對一、一對多、多對多、詳解