python - Django 中的复合外键

标签 python django postgresql django-models

我需要 Django 中的复合外键,但不受支持。我可以将它手动添加到数据库中,或通过迁移添加,但它不会反射(reflect)在模型定义 (sadpanda) 中。 后端数据库是 postgres。

这是我的模型:

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')

我想在 ComponentOverride 表的 trial_id 和 kit_id 列(模型中的 trial 和 kit)的外键约束到 trial 表上的 id 和 kit id 列(id 由 django 自动创建,模型中的 kit是表格中的 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;

我认为我需要组合键,因为每次试验可以覆盖多个组件。

一个试用版有一个套件,其中包含许多组件。然而,试验可能有一个或多个组件覆盖,这实际上是从套件中取出一个组件并用另一个组件替换它。这个模式明确地捕获了那个替换的信息,这就是为什么我不能同时使用 unique 的原因。我想确保 componentoverride 表中的每个 trial_id、kit_id 组合在 trial 表中都是有效组合。

最佳答案

针对上述情况的简单解决方案是从 ComponentOverride 中省略 kit。如果您从 ComponentOverride 引用 Trial,则您通过 trial__kit_id 隐式引用了试用套件。通过在 ComponentOverride 中另外保存 kit_id,您将不必要地复制数据。通过不保存相同的数据两次,约束问题就会自行消失。

(这是一个老问题,但吸引人的标题仍然为它引来了一些流量,所以也许上面的内容可以让一些人在不需要的时候免于陷入复合外键的困境。)

关于python - Django 中的复合外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42165838/

相关文章:

python - conda 虚拟环境不适用于 pycharm

python - 无法使用 kwargs 解决 Django "NoReverseMatch"异常

sql - 使用最后一个非空值更新有序行

php - Doctrine2 LEFT JOIN condition1 OR condition2

python - 拆分小写和大写联合的句子

python - 如何使用 Sage 找到 SPQR 树?

python - Django 缓存 - Pickle 很慢

python - 基本 Python、Django、DRY - 从(模型)类调用方法

python - 如何从数据库中检索密码

python - 使用自定义Python包