Class that extends a model that is not a model

40 views
Skip to first unread message

Domagoj Kovač

unread,
Mar 5, 2014, 8:03:53 AM3/5/14
to django...@googlegroups.com
Hi Guys,

I have a model called Calculation, this model has fields that are calculated and saved to the database, this model also hold some common calculation functions.

I also have two other classes TrailerCalculation and TruckCalculation they both calculate values of the fields that will be saved to Calculation, they calculate same properties but in a different way. So i extended Calcution with TrailerCalculation and TruckCalculation. Is there some way that child classes don't need to be models even though they inherit a class that inherits a model.Models? I tried with class Meta: abstract = True but this gives me some kind of strange error.

Best,
Domagoj

Kelly Nicholes

unread,
Mar 5, 2014, 9:43:28 AM3/5/14
to django...@googlegroups.com
Just a guess, but have you tried putting it in a file not called models.py?

Domagoj Kovač

unread,
Mar 5, 2014, 9:50:02 AM3/5/14
to django...@googlegroups.com
I did not try that, and i don't think this would help. Separation to more files doesn't have anything to do with the way works, theoretically your whole code can be just one file.

Tom Evans

unread,
Mar 5, 2014, 10:52:08 AM3/5/14
to django...@googlegroups.com
Your derived classes are models, and they should be models. What they
shouldn't be is have different tables for each model type, there
should be one table that all instances are stored in to, as the data
for each Calculation instance, regardless of type, is the same.

This is a common idiom in ORMs, and is called Single Table Inheritance:

http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html

Django doesn't support STI, but that doesn't really matter, you can
get the same behaviour by using composition rather than inheritance,
something like this:

CALC_TYPE_MAP = {
'trailer': TrailerCalculation,
'truck': TruckCalculation,
}

class Calculation(models.Model):
.....
#
def calculate(self):
calculator = CALC_TYPE_MAP[self.calculation_type]()
calculator.calculate(self)

TrailerCalculation and TruckCalculation do not derive from
Calculation, they are simply objects that provide functionality to
Calculation. This approach is called "Composition over inheritance".

Cheers

Tom

Domagoj Kovač

unread,
Mar 5, 2014, 11:05:06 AM3/5/14
to django...@googlegroups.com, teva...@googlemail.com
Thanks Tom, this looks like something that can help me. Thanks!

Javier Guerra Giraldez

unread,
Mar 5, 2014, 11:10:34 AM3/5/14
to django...@googlegroups.com
On Wed, Mar 5, 2014 at 10:52 AM, Tom Evans <teva...@googlemail.com> wrote:
> Your derived classes are models, and they should be models. What they
> shouldn't be is have different tables for each model type, there
> should be one table that all instances are stored in to, as the data
> for each Calculation instance, regardless of type, is the same.
>
> This is a common idiom in ORMs, and is called Single Table Inheritance:
>
> http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
>
> Django doesn't support STI, but that doesn't really matter, you can
> get the same behaviour by using composition rather than inheritance,
> something like this:

that sounds very similar to django's proxy models:

https://docs.djangoproject.com/en/1.6/topics/db/models/#proxy-models

but I agree that this kind of problems are typically better solved byt
composition rather than inheritance.

--
Javier

Domagoj Kovač

unread,
Mar 6, 2014, 5:50:38 AM3/6/14
to django...@googlegroups.com
Thanks Havier, 

Proxy models also look like something that fit my needs.
Reply all
Reply to author
Forward
0 new messages