2009-11-05 17 views
0

我的应用程序使用类继承来尽量减少我的模型重复。我的models.py看起来有点像这样:在Django的父级实例中找到一个子实例最简单的方法是什么?

class BaseModel(models.Model): 
    title = models.CharField(max_length=100) 
    pub_date = models.DateField() 

class Child(BaseModel): 
    foo = models.CharField(max_length=20) 

class SecondChild(BaseModel): 
    bar = models.CharField(max_length=20) 

现在大部分的时间,我的意见和模板只处理与儿童或SecondChild的实例。然而,偶尔有一种情况,我有一个BaseModel实例,需要弄清楚哪个类正在从这个实例继承。

给定一个BaseModel的实例,我们称它为base,Django的ORM提供base.child和base.secondchild。目前,我有一个方法循环遍历所有这些方法。它看起来是这样的:

class BaseModel(models.Model): 
    ... 
    def get_absolute_url(self): 
     url = None 
     try: 
     self.child 
     url = self.child.get_absolute_url() 
     except Child.DoesNotExist: 
     pass 
     if not url: 
     try: 
      self.secondchild 
      url = self.secondchild.get_absolute_url() 
     except SecondChild.DoesNotExist: 
      pass 
     if not url: 
     url = '/base/%i' % self.id 
     return url 

这是绝望丑陋的,并与我拥有的每一个额外的孩子班级丑陋。有没有人有更好的,更pythonic的方式来做到这一点?

回答

0

这个问题的各种形式定期弹出。 This answer演示了一种通用方法,可以将父类型“转换”为其适当的子类型,而无需查询每个子类型表。这样你就不需要在父类中定义一个包含所有情况的怪物get_absolute_url,你只需要转换为子类型并正常调用get_absolute_url即可。

0

我没有测试过这一点,但它可能是值得摆弄:

def get_absolute_url(self): 
    subclasses = ('child', 'secondchild',) 

    for subclass in subclasses: 
     if hasattr(self, subclass): 
      return getattr(self, subclass).get_absolute_url() 

    return '/base/%i' % self.id 
+1

最后如果不是真的需要,是吗? – Macke 2009-11-05 21:36:21

+0

谢谢!男人,我觉得很愚蠢。 – Udbhav 2009-11-05 21:47:08

0

我没有使用Django搞砸inheitance多,所以我想你不能覆盖模型get_absolute_url()班?

也许访问者模式可以帮助,如果有很多功能,需要在许多不同的地方这一点。

+0

我重写了它,但有时候,我必须使用父类,它无法访问它的子节点的get_absolute_url,直到我确定它是什么样的子节点为止。 – Udbhav 2009-11-05 21:36:21

相关问题