Django ForeignKey與數(shù)據(jù)庫的FOREIGN KEY約束詳解
數(shù)據(jù)庫在高并發(fā)的場景下使用外鍵約束會有鎖問題并且使用外鍵會增加運維成本,所以很多公司都規(guī)定生產(chǎn)環(huán)境的數(shù)據(jù)庫禁止使用外鍵。
那么不使用外鍵約束的情況下使用 Django ORM 如何實現(xiàn)關聯(lián)查詢兩個表呢?這曾是困擾我很久的一個問題,今天終于找到了答案,寫出來分享一下。
Django 的 ForeignKey 和數(shù)據(jù)庫的 FOREIGN KEY 并不一樣。Django 的 ForeignKey 是一種邏輯上的兩個表的關聯(lián)關系,可以指定是否使用數(shù)據(jù)庫的 FOREIGN KEY 約束。
在開頭提到的場景下,我們可以這樣創(chuàng)建兩個表對應的 Model,以省和市的關聯(lián)舉例:
# demo/models.pyfrom django.db import modelsclass Province(models.Model): name = models.CharField(max_length=16) def __unicode__(self): return self.nameclass City(models.Model): name = models.CharField(max_length=16) province = models.ForeignKey(Province, null=True, on_delete=models.SET_NULL, related_name=’cities’, db_constraint=False) def __unicode__(self): return self.name
以上的 models.py 在執(zhí)行 migrate 時生成的 SQL 如下(MySQL數(shù)據(jù)庫):
CREATE TABLE `demo_city` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(16) NOT NULL);CREATE TABLE `demo_province` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(16) NOT NULL);ALTER TABLE `demo_city` ADD COLUMN `province_id` integer NULL;CREATE INDEX `demo_city_province_id_50fffd49` ON `demo_city` (`province_id`);
如果 ForeignKey 不添加db_constraint=False 參數(shù),會在數(shù)據(jù)庫中使用外鍵約束,生成以下SQL:
ALTER TABLE `demo_city` ADD CONSTRAINT `demo_city_province_id_aff53934_fk_key_province_id` FOREIGN KEY (`province_id`) REFERENCES `demo_province` (`id`);
另外,F(xiàn)oreignKey 的 on_delete 參數(shù)默認為 on_delete=models.CASCADE,表示使用數(shù)據(jù)庫的級聯(lián)刪除,使用 on_delete=models.SET_NULL 可以使刪除 Province 時將關聯(lián)的 City 表對應的 province_id 值設為 NULL
使用這種方式不會破壞 Django 的反向關聯(lián)查詢,以下查詢?nèi)匀粫祷卣_的結(jié)果:
Province.objects.filter(cities__name=’xxx’)
實際執(zhí)行的 SQL 為一個 Inner Join 查詢:
SELECT `demo_province`.`id`, `demo_province`.`name` FROM `demo_province` INNER JOIN `demo_city` ON (`demo_province`.`id` = `demo_city`.`province_id`) WHERE `demo_city`.`name` = xxx;
補充知識:關于Django模型中中定義auto_now=True 數(shù)據(jù)庫中的時間并沒有自動更新
django的orm關于更新數(shù)據(jù)庫的方法有update和save兩種方法。
前提在模型中設置了auto_now=True時間戳屬性,為了方便數(shù)據(jù)庫自動更新時間,而
使用update更新的記錄,數(shù)據(jù)庫中并沒有自動更新,達到我的需求。
auto_now=True自動更新,有一個條件,就是要通過django的model層。
如create或是save方法。
如果是filter之后update方法,則直接調(diào)用的是sql,不會通過model層,
所以不會自動更新此時間。所以使用save方法更新才能達到我的需求。
以上這篇Django ForeignKey與數(shù)據(jù)庫的FOREIGN KEY約束詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。
相關文章:
1. python共軛梯度法特征值迭代次數(shù)討論2. 利用FastReport傳遞圖片參數(shù)在報表上展示簽名信息的實現(xiàn)方法3. H5頁面使用audio標簽播放音頻4. ASP.NET MVC視圖頁使用jQuery傳遞異步數(shù)據(jù)的幾種方式詳解5. CSS3使用過度動畫和緩動效果案例講解6. ASP.NET MVC通過勾選checkbox更改select的內(nèi)容7. react axios 跨域訪問一個或多個域名問題8. 詳解php如何合并身份證正反面圖片為一張圖片9. AJAX實現(xiàn)省市縣三級聯(lián)動效果10. XHTML 1.0:標記新的開端
