如何在查询基类时获取专门的Django模型实例?

时间:2013-10-25 08:44:09

标签: python django

我在管理远程主机的应用程序中有Django multi-table model inheritance的经典用例。

该应用程序可以使用通用的“RemoteHost”,或“SshHost”(也是一个RemoteHost),或“EsxiHost”(也是一个SshHost),所以很自然地我去了多表模型继承:

class RemoteHost(models.Model):
    ...
    def shutdown(self):
        raise NotImplemented()

class SshHost(RemoteHost):
    ...
    def shutdown(self):
        # run SSH shutdown command

class EsxiHost(SshHost):
    ...
    def shutdown(self):
        # shutdown running virtual machine using VMware API
        SshHost(self).shutdown()

我希望能够在不知道特定主机类型的情况下“关闭”托管主机,例如RemoteHost.objects.get(pk=1).shutdown(),但事实证明Django数据模型将返回明确请求的类型(根据我的经验,以及the docs)。

我正在寻找一种干净的方法来获取基于基类查询集的最专业的实例。

到目前为止,我提出的“最干净”的方法看起来像这样:

class RemoteHost(models.Model):
    ...
    def get_specialized_instance(self):
        try:
            return self.sshhost.get_specialized_instance()
        except self.DoesNotExist:
            return self

class SshHost(RemoteHost):
    ...
    def get_specialized_instance(self):
        try:
            return self.esxihost.get_specialized_instance()
        except self.DoesNotExist:
            return self

class EsxiHost(SshHost):
    ...
    def get_specialized_instance(self):
        return self

这种方法的优点是它起作用: - )

但我不喜欢它,原因如下:

  1. 它要求使用代码在对象上显式调用get_specialized_instance()
  2. 它要求基础模型了解扩展它们的模型。
  3. 因此,欢迎任何有关更好/更清洁的方法的建议!

1 个答案:

答案 0 :(得分:1)

Django Polymorphic可能是您的朋友,而不是编写自己的ObjectManagers并设置ContentTypes,它为您完成所有繁重的工作。你去,一个正确的答案! : - )