16

I have a class called BankAccount as base class. I also have CheckingAccount and SavingsAccount classes that inherit from BankAccount.

BankAccount is not an abstract class but I do not create an object from it, only the inheriting classes.

Then, I execute a query like this:

account = BankAccount.objects.get(id=10)

How do I know if account is CheckingAccount or SavingsAccount?

The way I do this now is in this way:

checking_account = CheckingAccount.objects.get(id=account.id)

If it exists, it is a CheckingAccount, otherwise, it is a SavingsAccount.

Esteban Küber
  • 36,388
  • 15
  • 79
  • 97
dannyroa
  • 5,501
  • 6
  • 41
  • 59
  • I'm having a similar problem. Check my approach! http://stackoverflow.com/questions/12411232/django-multi-table-inheritance-how-to-know-which-is-the-child-class-of-a-model – luistm Sep 17 '12 at 12:47

4 Answers4

12

Try to use the checkingaccount and savingsaccount attributes. The one it is will not blow up.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 1
    What if the attribute name is only known at runtime? – Izz ad-Din Ruhulessin Aug 14 '11 at 12:53
  • At runtime, assume you have selected a base `BankAccount` object named `account` and the variable attribute name is `attr_name`. Run `hasattr(account, attr_name)` and you will get True if there is a subclass of that type, or False if it doesn't. – Furbeenator Feb 05 '15 at 18:55
  • v1.9 link describing this multi-table inheritance: https://docs.djangoproject.com/en/1.9/topics/db/models/#multi-table-inheritance – MrDBA May 27 '16 at 09:34
11

You could use isinstance(account, SavingsAccount), but is generally preferred to avoid it and use duck type inference by looking at the object's attributes, and see if it quacks like a subclass.

To see if an object has an attribute, you use the aptly named hasattr built-in function or use getattr and check for the raising of an AttributeError exception.

Esteban Küber
  • 36,388
  • 15
  • 79
  • 97
0

After some more searching I found solutions akin to this: Django multi-table inheritance, how to know which is the child class of a model?

Basically, there's no elegant solution for this. You have to do a bunch of try-except statements and force django to use the class you want.

Community
  • 1
  • 1
i41
  • 311
  • 2
  • 9
0

Add a GetAccountType() method to your Checking and Savings accounts, when you get the object back from BankAccount.objects.get() then call that, if everything that derives from BankAccount has that method then you'll be fine.

Fraser Graham
  • 4,650
  • 4
  • 22
  • 42