2009-11-05 4 views
0

Mon application utilise l'héritage de classe pour minimiser la répétition dans mes modèles. Mon models.py ressemble un peu comme ceci:Quelle est la manière la plus simple de trouver une instance enfant depuis une instance parent dans 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) 

Maintenant, la plupart du temps, mon point de vue et les modèles portent uniquement sur les cas d'enfants ou SecondChild. De temps en temps, cependant, j'ai une situation où j'ai une instance de BaseModel, et j'ai besoin de comprendre quelle classe hérite de cette instance.

Étant donné une instance de BaseModel, appelons-la base, ORM de Django propose base.child et base.secondchild. Actuellement, j'ai une méthode qui les traverse tous pour le comprendre. Il ressemblerait à quelque chose comme ceci:

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 

C'est désespérément laid, et obtient plus laid avec chaque classe enfant supplémentaire que j'ai. Est-ce que quelqu'un a des idées sur une façon meilleure, plus pythonique de s'y prendre?

Répondre

0

Différentes formes de cette question apparaissent régulièrement ici. This answer illustre une manière générique de "convertir" un type parent en son propre sous-type sans devoir interroger chaque table de sous-types. De cette façon, vous n'auriez pas besoin de définir un monstre get_absolute_url sur le parent qui couvre tous les cas, vous devriez juste convertir en le type enfant et appeler normalement get_absolute_url.

0

Je n'ai pas testé, mais il pourrait être utile de bricoler:

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

le dernier si ce n'est pas vraiment nécessaire, n'est-ce pas? – Macke

+0

Merci! Mec, je me sens si stupide. – Udbhav

0

Je n'ai pas sali avec Django inheitance beaucoup, donc je suppose que vous ne pouvez pas remplacer get_absolute_url() dans le modèle Des classes?

Peut-être que le modèle de visiteur pourrait aider s'il y a beaucoup de fonctions qui ont besoin de cela dans de nombreux endroits différents.

+0

Je le remplace, mais parfois, je dois utiliser la classe parent, qui n'a pas accès à get_absolute_url de ses enfants, jusqu'à ce que je comprenne ce que c'est réellement. – Udbhav

Questions connexes