There's plenty of document and discussion for having multiple models share fields in a parent class/table using "concrete" or "multi-table" inheritance:
class Place(models.Model):
...
class Restaurant(Place):
...
However, I can't find much on the inverse use-case: splitting the fields of a single model across multiple tables to save the cost of loading wide columns except when you actually need them.
Consider the following scenario:
class Person_Profile(models.Model):
...lots of fields...
class Person_Preferences(models.Model):
...lots of fields...
class Person(Person_Profile, Person_Preferences):
...small set of core fields...
What works:
- When you create a Person, the other two objects are automatically created and linked for you.
- You can access profile and preference fields directly on Person. (
person.some_field
)
The only thing I'm missing is how to elegantly control when Django loads the fields from the parent table, since currently, loading a Person with p = Person.objects.first()
results in all three tables being joined and selected by default.
UPDATE
I went looking for how Django let's you express selecting a subset of fields and arrived at the QuerySet methods defer() and only(), along with the suggestion there about using an unmanaged model as a facade to conveniently load a subset of fields:
class Person(models.Model):
name = models.CharField(max_length=30)
pref1 = models.BooleanField(default=False)
profile1 = models.CharField(max_length=30, null=True)
class SkinnyPerson(models.Model):
name = models.CharField(max_length=30)
class Meta:
managed = False
db_table = 'myapp_person'
Haven't reach a conclusion yet, but this method has a lot of appeal right now.