You want an abstract base class ("virtual" means nothing in Python.)
From the documentation:
class CommonInfo(models.Model): name = models.CharField(max_length=100) age = models.PositiveIntegerField() class Meta: abstract = True
Edit
"When programming OO when calling object.method (), you should get an implementation of the lowest subclass."
True But not the whole story.
This is not an OO problem. Or even a Python or Django problem. This is a problem with ORM.
Question: "What object was reconstructed at the end of the FK directory?" And the answer is that there is no standard, obvious answer on how to handle the conversion from the FK value to an object.
I have a line in AnimalHome with animals value 42. It refers to Animal.objects.get(pk=42) . What is the subclass of animals? Cat? Dog? How does the ORM level know if it should do Dog.objects.get(pk=42) or Cat.objects.get(pk=42) ?
"But wait, you say." It should get an Animal object, not a Dog or Cat object. "You can hope so, but that’s not how Django ORM works. Each class is a separate table. Cat and Dog are, by definition, separate tables with separate queries. You You don’t use object storage, you use ORM for relational tables.
Edit
Firstly, your request only works if Dog and Cat have a common key generator and do not have an overlapping PK set.
If you have a dog with a PC of 42 and a cat with a PC of 42, you have a problem. And since you cannot easily manage key generation, your solution may not work.
Runtime type identification is poor. This is not Object-Oriented in several ways. Almost everything you can do to avoid RTTI is better than an ever-expanding sequence of if statements to distinguish between subclasses.
However, the model you are trying to build is, in particular, a pathological problem for ORM systems. Indeed, it is so specifically pathological that I am almost ready to bet on homework. [There are also pathological problems for pure SQL systems. They often appear as homework.]
The problem is that ORM cannot do what you think should do. Thus, you have two options.
- Stop using Django.
- Do something Django directly.
- Go to the OO design guide and resort to fragile things like RTTI, which makes it extremely difficult to add another subclass of animals.
Consider this method to make RTTI - it includes the class name as well as PK
KIND_CHOICES = ( ( "DOG", "Dog" ), ( "CAT", "Cat" ), ) class Animal( models.Model ): kind = models.CharField( max_length= 1, choices=KIND_CHOICES ) fk = models.IntegerField() def get_kind( self ): if kind == "DOG": return Dog.objects.get( pk = fk ) elif kind == "CAT": return Cat.objects.get( pk = fk )