Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a django model have two abstract classes?

I have this models:

class BillHeader(models.Model):
    billno = models.IntegerField(primary_key=True, blank=True)

class BillData(models.Model):
    price = models.DecimalField(_('Price'), max_digits=12, decimal_places=2)
    amount = models.DecimalField(_('Amount'), max_digits=6, decimal_places=2)

    [... rest of the model ...]

    class Meta:
        abstract = True

class BillFooter(models.Model):
    total = models.DecimalField(_('Total'), max_digits=12, decimal_places=2)

    [... rest of the model ...]

    class Meta:
        abstract = True

BillData and BillFooter are common to every BillHeader so I've marked them as abstract. Can I do class BillHeader(BillData, BillFooter) or I'm doing something wrong?

I also thought about doing BillData the main one, and BillHeader BillFooter abstract. I don't have any experience on doing data models (at least not complex ones) and I'm a bit lost. What would you recommend?

like image 766
CastleDweller Avatar asked Jun 29 '10 19:06

CastleDweller


People also ask

Can we inherit multiple abstract classes in Python?

Inheriting Multiple Classes. Python is one of the few modern programming languages that supports multiple inheritance.

Does Django support multiple inheritance?

You Inherit from base class and you can add your own properties except fields. base class should not be abstract class. we can not use multiple inheritance in proxy models.

What is abstract class in Django?

An abstract model is a base class in which you define fields you want to include in all child models. Django doesn't create any database table for abstract models. A database table is created for each child model, including the fields inherited from the abstract class and the ones defined in the child model.

Why do we use abstract models in Django?

Abstract Base Class are useful when you want to put some common information into a number of other models. You write your base class and put abstract = True in the Meta Class.


1 Answers

Yes, a Django model can inherit from as many abstract base classes as you like, as long as they don't result in an ambiguous "model resolution order". Think of inheritance as a chain... each class you inherit from is a link in the chain. Inheriting from two base classes is just adding two links to the chain instead of one.

In other words, if your abstract base classes inherit from models.Model, then don't try to inherit from both the abstract base class and models.Model in your Bill class. models.Model is already in the inheritance chain, so inheriting from it causes chaos in the chain of base classes.

As to how I would structure these classes, I would create a model called Bill that inherited from BillHeader, BillData, and BillFooter. The reason for this is that I like my Django models to represent discrete objects (e.g. Bill, Article, BlogPost, Photo, etc.)

However, the point of abstract base classes is to be able to add a level of abstraction to common fields and methods so that multiple classes can inherit from them. If you're just creating a Bill class it's somewhat meaningless. If, however, you had Bill, and UnpaidBill, and PaidBill... all of those would have common fields that should appear on all of them and you can save yourself a lot of trouble by abstracting to an ABC.

Hopefully that offers a little insight to what ABC's and inheritance are good for.

like image 168
Gabriel Hurley Avatar answered Sep 28 '22 05:09

Gabriel Hurley