2017-02-10 202 views
2

我需要Django中的複合外鍵,這是不受支持的。我可以手動將它添加到數據庫,或通過遷移,但它不會反映在模型定義(sadpanda)中。 後端數據庫是postgres。Django中的複合外鍵

這裏是我的模型:

class Trial(models.Model): 
    kit = models.ForeignKey(to='Kit') 

class Kit(models.Model): 
    name = models.CharField(max_length=500) 


class Component(models.Model): 
    kit = models.ForeignKey(null=True, blank=True, to='Kit', related_name='components') 


class ComponentOverride(models.Model): 
    trial = models.ForeignKey(to='Trial') 
    kit = models.ForeignKey(to='Kit') 
    component_to_replace = models.ForeignKey(to='Component', related_name='replaced') 
    component_replace_with = models.ForeignKey(to='Component', related_name='replaced_with') 

我要上試用表的列trial_id和kit_id(試行及配套的機型)的ID和包ID列ComponentOverride表的外鍵約束(id是由django自動創建的,模型中的工具包是表中的kit_id)。

基本上我想一個等同於:

ALTER TABLE app_label_trial 
    ADD CONSTRAINT app_label_trial_unique_trial_id_kit_id 
    UNIQUE (id, kit_id); 
ALTER TABLE app_label_componentoverride 
    ADD CONSTRAINT app_label_componentoverride_comp_constraint_trial_id_kit_id 
    FOREIGN KEY (kit_id, trial_id) 
    REFERENCES app_label_trial(id, kit_id) 
    DEFERRABLE INITIALLY DEFERRED; 

我想我需要的是組合鍵,因爲可以有每次試驗的多個組件覆蓋。

試用版有一個套件,它有很多組件。然而,試用版可能會有一個或多個組件覆蓋,這基本上是從套件中取出一個組件,並用另一個替換它。這個模式明確地捕獲了替換的信息,也是爲什麼我不能一起使用唯一。我想確保組件覆蓋表中的每個trial_id,kit_id組合都是試用表中的有效組合。

+1

我可以問爲什麼你認爲你需要一個複合鍵嗎?通常的解決方案是使用'unique_together'代替 – Sayse

+1

好問題,我已經編輯了上面的問題來解釋。謝謝。 –

回答

0

最後我把這個在我最初的遷移結束:

migrations.RunSQL(""" 
      ALTER TABLE qc_trials_trial 
       ADD CONSTRAINT qc_trials_trial_unique_trial_id_kit_id 
       UNIQUE (id, kit_id); 
      ALTER TABLE qc_trials_componentoverride 
       ADD CONSTRAINT qc_trials_componentoverride_comp_constraint_trial_id_kit_id 
       FOREIGN KEY (kit_id, trial_id) 
       REFERENCES qc_trials_trial(id, kit_id) 
       DEFERRABLE INITIALLY DEFERRED 
"""), 

如果這是我的預期不得不做了很多,我會寫一個自定義的操作它。 https://docs.djangoproject.com/en/1.10/ref/migration-operations/#writing-your-own