【问题标题】:Django: foreign key to two modelsDjango:两个模型的外键
【发布时间】:2019-07-30 22:55:03
【问题描述】:

我正在尝试在 Django 中构建一个应用程序。假设我有这个模型:

class Server(model.Models):
    hosted_by = models.ForeignKey('Self', limit_choices_to={'backup_server': True})
    host = models.BooleanField(default=False)

这个类定义了一个服务器。

每个服务器都可以是主机,这意味着它可以托管其他服务器(虚拟)。 因此,每个服务器都可以由其他服务器托管。这很简单。

但问题是:主机可以是主机集群的一部分。因此,虚拟服务器可以由独立主机或集群托管。当服务器由集群托管时,我不想指定集群中的哪个主机。

我不知道如何管理“hosted_by”。我尝试使用 Contenttype 和泛型关系,但它在管理部分根本不是用户友好的。

我创建了一个新模型:

class Cluster(models.Model):

所以我的服务器现在是这样的:

class Server(model.Models):
    hosted_by = models.ForeignKey('Cluster' ...)
    host = models.BooleanField(default=False)
    member_of_cluster = models.ForeignKey('Cluster' ...)

除了我的服务器两次链接到集群(但使用related_name 它可以工作)这一事实之外,现在主机只能链接到集群...

有没有一种简单易行的方法来做类似的事情:

hosted_by = models.ForeignKey('Self' OR 'Cluster', ...) 

这对我来说很有用:P

无论如何,我有点坚持这一点。当然我可以这样做:

hosted_by_cluster = models.ForeignKey('Cluster' ...)
hosted_by_standalone_host = models.ForeignKey('Self', limit_choices_to={'backup_server': True})
host_standalone = models.BooleanField(default=False)
member_of_cluster = models.ForeignKey('Cluster' ...)

但我不确定我是否喜欢这个主意......

另外,在认真考虑这一点之前,我尝试过将每个主机都放在一个集群中。因此,我将拥有只有一台主机的集群。我也不确定这是否是个好主意。

任何帮助将不胜感激。提前致谢!

【问题讨论】:

  • +1 表示 100 分之一的“新用户问题”我没有回答,但实际上是可以理解的。

标签: django django-models foreign-keys


【解决方案1】:

您可以删除外键上的默认 not null 约束:

class Server(model.Models):
    hosted_by = models.ForeignKey('Self', blank=True, null=True, ...)
    host = models.BooleanField(default=False)
    member_of_cluster = models.ForeignKey('Cluster', blank=True, null=True, ...)

然后,在您的数据库上创建触发器以将 hosted_by 列设置为 null 每当一个值被添加或更新到 member_of_cluster

DELIMITER $$
CREATE TRIGGER before_insert_server
BEFORE INSERT ON server
FOR EACH ROW 
BEGIN
IF NEW.member_of_cluster IS NOT NULL THEN
    SET NEW.hosted_by = NULL;
END IF;
END $$

CREATE TRIGGER before_update_server
BEFORE UPDATE ON server
FOR EACH ROW 
BEGIN
IF NEW.member_of_cluster IS NOT NULL THEN
    SET NEW.hosted_by = NULL;
END IF;
END $$
DELIMITER ;

注意,我不知道您使用的是什么数据库,并且触发器语法是为 MySQL 编写的,我不确定这是否适用于您的情况,或者这是否适用总的来说,这是一个好主意。这就是我想到的。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    经过深思熟虑,我决定采用每个托管服务器都在一个集群中的解决方案。这样,如果需要,我可以将其他服务器添加到集群中。

    【讨论】:

      猜你喜欢
      • 2015-12-21
      • 2010-10-29
      • 2021-10-31
      • 2013-01-17
      • 2017-10-24
      • 2011-12-04
      • 1970-01-01
      • 2020-11-26
      • 2011-12-03
      相关资源
      最近更新 更多