Get child model

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Parent(models.Model):

  child_class_names = (
    'Child1',
    'Child2',
    'Child3',
  )

  def child_object(self):
    for child_class_name in self.child_class_names:
      try:
        return self.__getattribute__(child_class_name.lower())
      except eval(child_class_name).DoesNotExist:
        pass
    return self


class Child1(Parent):
  pass

class Child2(Parent):
  pass

class Child3(Parent):
  pass

More like this

  1. Custom optional abstract base attributes by tie 5 years, 10 months ago
  2. Child aware model inheritance by rix 5 years, 5 months ago
  3. Get actual child model in multi-table inheritance by bronger 3 years, 9 months ago
  4. update primary key (cascade to child tables and inherited models) by variant 11 months, 4 weeks ago
  5. Changing field type in production by lawgon 7 years ago

Comments

andreas (on May 10, 2008):

This will is not a good solution since it will lead to lots of unnecessary load on the database (each self. will be a select query, possible with joins)

#

Hangya (on May 10, 2008):

Well, this may be true; please tell me if you know a better solution or a workaround for this task, which I need often...

#

andreas (on May 11, 2008):

I need aswell but i dont think there is any at the moment. This has been discussed on the irc channel.

#

edwardgeorge (on May 11, 2008):

how about adding a field to Parent called object_name and override the save method on Parent to assign

self.object_name = self._meta.object_name

I've just tried this in some of my code and it works for me

#

edwardgeorge (on May 11, 2008):

then in place of the child_object method in the example above you could use the following descriptor on Parent to get the child object:

child_object = property(lambda self: getattr(self, self.object_name.lower()))

#

(Forgotten your password?)