Model inheritance with content type

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from django.contrib.contenttypes.models import ContentType

class Contact(models.Model):

    content_type = models.ForeignKey(ContentType,editable=False,null=True)

    def save(self):
        if(not self.content_type):
            self.content_type = ContentType.objects.get_for_model(self.__class__)
        self.save_base()

    def as_leaf_class(self):
        content_type = self.content_type
        model = content_type.model_class()
        if(model == Contact):
            return self
        return model.objects.get(id=self.id)

More like this

  1. IfValueTag by adurdin 6 years, 3 months ago
  2. DRY Fieldsets by DrMeers 4 years ago
  3. Email Munger by cootetom 4 years, 5 months ago
  4. Model inheritance with content type and inheritance-aware manager by dan90 4 years, 9 months ago
  5. Form splitting/Fieldset templatetag by peritus 4 years, 9 months ago

Comments

dan90 (on September 7, 2008):

awesome snippet, crucialfelix.

I've taken your snippet and tacked on a complementary QuerySet hack of my own to avoid having to manually call the as_leaf_class method.

#

tygielzchaosem (on January 30, 2009):

One may achieve a similar goal without using ContentType. I suppose this boosts performance by omitting one DB hit if used with select_related():

class Base(models.Model):
    classname = models.CharField(max_length=32, editable=False, null=True)

    def save(self):
        self.classname = self.__class__.__name__
        self.save_base()

    def get_concrete(self):
        return self.__getattribute__(self.classname.lower())

This solution is, though, limited to only one inheritance level, but it could be extended by adding further get_concrete() to child classes.

#

shaun (on October 8, 2010):

This snippet is now included in django-snippetscream

#

vdboor (on May 19, 2013):

For a sophisticated solution, consider looking at django-polymorphic too!

#

(Forgotten your password?)