views:

209

answers:

4

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.

+3  A: 

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

Ignacio Vazquez-Abrams
Link: http://docs.djangoproject.com/en/1.1/topics/db/models/#id7
Felix Kling
A: 

A little janky, but this would work:

>>> class BankAccount(object): pass
...
>>> class SavingsAccount(BankAccount): pass
...
>>> class CheckingAccount(BankAccount): pass
...
>>> x = SavingsAccount()
>>> type(x) == type(SavingsAccount())
True
>>> type(x) == type(CheckingAccount())
False
inkedmn
`type(x) == SavingsAccount` does the same without creating a new object.
Felix Kling
This will fail horribly if you're querying from `BankAccount`. Django does not auto-promote models.
Ignacio Vazquez-Abrams
A: 

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.

voyager
Again, won't work if you're querying off `BankAccount`.
Ignacio Vazquez-Abrams
A: 

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
`BankAccount.objects.get()` returns a `BankAccount` object. Always.
Ignacio Vazquez-Abrams
You're right, I thought I was using something similar in my own code but I checked and i'm only ever doing queries based on the derived class.
Fraser Graham