2013-10-25 14 views
0

我有一個Django經典用例multi-table model inheritance,在一個管理遠程主機的應用程序中。如何在查詢基類時獲取專門的Django模型實例?

該應用程序可以與泛型「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. 它要求基礎模型知道擴展它們的模型。

因此,任何關於更好/更乾淨的方式來達到此目的的建議將受到歡迎!

+0

看到'相關'部分的權利,aswer似乎是正確的:http://stackoverflow.com/questions/349206/how-do-i-find-the-concrete-class-of- a-django-model-baseclass?rq = 1 – alko

+1

[Django Polymorphic](https://github.com/chrisglass/django_polymorphic)可能是你的朋友,而不是編寫你自己的ObjectManagers並設置ContentTypes,它會完成所有的重爲你解除。 – professorDante

+0

@professorDante:謝謝!這就是我一直在尋找的! 只需要記住,它會造成數據庫開銷... 半元 - 爲什麼你回答這個評論而不是答案?我不能用這種方式將它標記爲「答案」... – Itamar

回答

1

Django Polymorphic可能是你的朋友,而不是寫你自己的ObjectManagers和設置ContentTypes,它爲你做了所有繁重的工作。你去,一個正確的答案! :-)