Child aware model inheritance

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

class Place(models.Model):
    name = models.CharField('name')
    content_type = models.ForeignKey(ContentType)
    # Child model
    child = generic.GenericForeignKey(fk_field='id')
    
    def save(self, **kwargs):
        if not self.pk:
            self.content_type = ContentType.objects.get_for_model(self)
        super(Place, self).save(**kwargs)
    
class Restaurant(Place):
    pass

More like this

  1. Custom Django manager that excludes subclasses by sciyoshi 4 years, 9 months ago
  2. ContentType Form by nosrednakram 3 years, 8 months ago
  3. Model inheritance with content type and inheritance-aware manager by dan90 4 years, 8 months ago
  4. Get child model by Hangya 5 years ago
  5. Polymorphic inheritance ala SQLAlchemy by gsakkis 2 years, 7 months ago

Comments

daevaorn (on November 14, 2008):

May be?

self.content_type = ContentType.objects.get_for_model(self.__class__)

#

rix (on November 14, 2008):

The get_for_model method accepts an instance also, I think it'll work in both cases.

#

carljm (on November 16, 2008):

This code is brittle, as I explain here. It's easy to make content_type have the wrong value, simply by loading and saving a Place object (that is actually a Restaurant too).

The fix is to only assign to self.content_type once, when the object is initially created (i.e. wrap the assignment in "if not self.id").

#

rix (on November 18, 2008):

You're right carljm, the code can be improved with your fix.

In my use, a Place is never created by itself, only through child classes, so I'd never got affected.

I'll fix the code, thanks for the tip.

#

(Forgotten your password?)