Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to go from a Model base to derived class in Django?

Assuming a simple set of inherited Model classes, like this:

class BaseObject(models.Model): 
    some_field = models.SomeField(...)

class AwesomeObject(BaseObject): 
    awesome_field = models.AwesomeField(...)

class ExcellentObject(BaseObject): 
    excellent_field = models.ExcellentField(...)

and a query that looks like this:

found_objects = BaseObject.objects.filter(some_field='bogus')

What's the best way to take each found object and turn it back into it's derived class? The code I'm using now is like this:

for found in found_objects:
    if hasattr(found, 'awesomeobject'): 
        ProcessAwesome(found.awesomeobject)
    elif hasattr(found, 'excellentobject'): 
        ProcessExcellent(found.excellentobject): 

But, it feels like this is an abuse of "hasattr". Is there a better way to do this without creating an explicit "type" field on the base class?

like image 539
slacy Avatar asked Jun 10 '11 18:06

slacy


People also ask

Can we inherit model in Django?

Models inheritance works the same way as normal Python class inheritance works, the only difference is, whether we want the parent models to have their own table in the database or not.

Can derived class objects be assigned to base class?

Object Slicing in C++ In C++, a derived class object can be assigned to a base class object, but the other way is not possible.

What is PK in Django model?

pk is short for primary key, which is a unique identifier for each record in a database. Every Django model has a field which serves as its primary key, and whatever other name it has, it can also be referred to as "pk".


1 Answers

For this specific problem, there is django-polymorphic. It works by using the content type framework in Django to store the model ID which the derived table points to. When you evaluate the queryset, it will upcast all models their specific type.

You'll get:

>>> BaseProject.objects.all()
[ <AwesomeObject>, <ExcellentObject>, <BaseObject>, <AwesomeObject> ]
like image 188
vdboor Avatar answered Oct 07 '22 02:10

vdboor