Meir
Meir

Reputation: 1711

Polymorphism in a Django model class

I have the following model.

CHOICES=( ('TEXT', 'TEXT'), ('IMAGE', 'IMAGE') )

type = models.CharField(max_length=10, blank=False, choices = CHOICES)
body = models.TextField()

If the type field is TEXT then the database row contains some plain text. If the type field is IMAGE then the database row contains an image file name.

I add a print_item function to the model class to handle both cases:

def print_item(self):
  if self.type == "TEXT":
      return self.body
  elif self.type == "IMAGE":
      return "<img src='%s' />" % self.body

This is obviously not a generic or OO way to do it. Another option would be to create two classes, image and text, both having a print_item function and then instantiate the object (based on the type string) and call its print_item function.

What is the best approach to take in this situation?

Upvotes: 1

Views: 264

Answers (2)

trez
trez

Reputation: 478

We fixed this OOP problem with proxies. I an proxy model, define your print_item function. The problem comes when you retrieve the object later as Django will use the base class instead of the proxy one.

I wrote a blog post about the full detailed solution here: http://anthony-tresontani.github.com/Python/2012/09/11/django-polymorphism/

Upvotes: 1

Udi
Udi

Reputation: 30472

As you said, your current solution is not really object-oriented or cool, but it keeps you with only one simple table in the db, and no foreign keys etc., which is also nice.

If you need to work a little more with each object, and have a nicer admin, you might find proxy models useful: http://lincolnloop.com/blog/2010/dec/16/using-proxy-models-customize-django-admin/ .

Upvotes: 0

Related Questions