Django:两个模型的外键

时间:2019-03-08 21:20:02

标签: django django-models foreign-keys

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

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

此类定义了服务器。

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

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

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

我创建了一个新模型:

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

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

此外,在认真考虑这个问题之前,我尝试过将每个主机都放在一个群集中。因此,我将仅拥有一台主机。我也不知道这是否是个好主意。

任何帮助将不胜感激。预先感谢!

2 个答案:

答案 0 :(得分:0)

您可以删除外键上的默认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编写的,并且不确定是否适用于您的情况,或者是否甚至是一个好主意。这就是我想到的。

希望这会有所帮助!

答案 1 :(得分:0)

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