Model Downcast in Django

Django has had multi-table inheritance for three months now, but I haven't used it because I can't picture many use cases for inheritance which don't rely on dynamic polymorphism.

In my current project, however, I've found a fairly convincing use case. I can do all of the basic listing and manipulation with the base class, and I only need the superclass for one particular operation.

Rather than writing this in a different way, which would be less intuitive, I pushed ahead with the conceptually simple approach and fought with Django to make the inheritance polymorphic. The way I did this was brute force it: check all of the relations for one that exists.

from django.db import models

cls = inst.class #inst is an instance of the base model

for r in cls._meta.get_all_related_objects(): if not issubclass(r.model, cls) or \ not isinstance(r.field, models.OneToOneField): continue try: return getattr(inst, r.get_accessor_name()) except models.ObjectDoesNotExist: continue

There are faster ways of doing this if you do it at the database level (left joining all tables in the inheritance hierarchy and sorting out the mess into the correct subclasses), but this is simple and self-contained and forces me to think about when I need this. And looking at the query cache, the overhead is not too bad anyway.

Comments

Comments powered by Disqus