django abstract models versus regular inheritance
I actually want to know the difference between a model class that inherits from a django abstract class (Meta: abstract = True) and a plain Python class that inherits from say, 'object' (and not models.Model).
Django will only generate tables for subclasses of models.Model
, so the former...
class User(models.Model):
first_name = models.CharField(max_length=255)
def get_username(self):
return self.username
class Meta:
abstract = True
class Employee(User):
title = models.CharField(max_length=255)
...will cause a single table to be generated, along the lines of...
CREATE TABLE myapp_employee
(
id INT NOT NULL AUTO_INCREMENT,
first_name VARCHAR(255) NOT NULL,
title VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
...whereas the latter...
class User(object):
first_name = models.CharField(max_length=255)
def get_username(self):
return self.username
class Employee(User):
title = models.CharField(max_length=255)
...won't cause any tables to be generated.
You could use multiple inheritance to do something like this...
class User(object):
first_name = models.CharField(max_length=255)
def get_username(self):
return self.username
class Employee(User, models.Model):
title = models.CharField(max_length=255)
...which would create a table, but it will ignore the fields defined in the User
class, so you'll end up with a table like this...
CREATE TABLE myapp_employee
(
id INT NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
An abstract model creates a table with the entire set of columns for each subchild, whereas using "plain" Python inheritance creates a set of linked tables (aka "multi-table inheritance"). Consider the case in which you have two models:
class Vehicle(models.Model):
num_wheels = models.PositiveIntegerField()
class Car(Vehicle):
make = models.CharField(…)
year = models.PositiveIntegerField()
If Vehicle
is an abstract model, you'll have a single table:
app_car:
| id | num_wheels | make | year
However, if you use plain Python inheritance, you'll have two tables:
app_vehicle:
| id | num_wheels
app_car:
| id | vehicle_id | make | model
Where vehicle_id
is a link to a row in app_vehicle
that would also have the number of wheels for the car.
Now, Django will put this together nicely in object form so you can access num_wheels
as an attribute on Car
, but the underlying representation in the database will be different.
Update
To address your updated question, the difference between inheriting from a Django abstract class and inheriting from Python's object
is that the former is treated as a database object (so tables for it are synced to the database) and it has the behavior of a Model
. Inheriting from a plain Python object
gives the class (and its subclasses) none of those qualities.