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. Model inheritance with content type and inheritance-aware manager by dan90 3 years, 5 months ago
  2. Copy a model instance by miracle2k 3 years, 5 months ago
  3. convenience parent class for UserProfile model by willhardy 2 years, 9 months ago
  4. Multiple User subclasses custom Auth backend by ungenio41 5 months ago
  5. Limit queryset to objects related to parent in ManyToMany fields within admin inlines by DrMeers 1 year, 8 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

#

(Forgotten your password?)