开发者

Django polymorphism hack

I'm trying to bake out a sort of "single table inheritence" a.k.a. "table per hierarchy" model in Django.

Here's what I'd like to do:

class PolymorphicModel(models.Model):

   content_type = models.ForeignKey(ContentType)

   class Meta:
       abstract = True

   def __init__(self, *args, **kwargs):
       super(PolymorphicModel, self).__init__(*args, **kwargs)
       # Dynamically switch the class to the actual one
       self.__class__ = self.content_type.model_class()

   def save(self, *args, **kwargs):
       if not self.content_type:
           # Save the actual class name for the future.
           self.content_type = ContentType.objects.get_for_model(self.__class__)
           super(PolymorphicModel, self).save(*args, **kwargs)

And then the actual hierarchy:

class Base(PolymorphicModel):

    a = models.IntegerField()
    b = models.IntegerField()

    @abstractmethod
    def som开发者_开发技巧ething(self): pass


class DerivedA(Base):

    def something(self):
        return self.a


class DerivedB(Base):

    def something(self):
        return self.b

Unfortunately I get an error DoesNotExist when constructing DerivedA(). It complains about content_type not existing.

EDIT:

Concerning my questions:

  • Why do I get the exception, how to fix it?

See my answer below: content_type is apparently not a viable name.

  • Is the thing that I'm trying to achieve doable this way?

Yes it is! And it works beautifully. Using class names instead of content type is also possible. This has an added value of handling proxy = True appropriately.


Ups, well apparently content_type is a reserved name. I changed the property name to ct and it works now.

I've published by solution here: http://djangosnippets.org/snippets/2408/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜