1👍
✅
You can use extra abstract models to alter the fields in the hierarchy:
class Parent(models.Model):
intfield = models.IntegerField()
class Meta:
abstract = True
class DescendantType1(Parent):
"""This is an abstract model that inherits from the Parent model, with the "type 1"
attributes.
"""
addedfield = models.CharField(max_length=20)
class Meta:
abstract = True
class DescendantType2(Parent):
"""This is an abstract model that inherits from the Parent model, with the "type 2"
attributes.
"""
addedfield2 = models.DecimalField(max_digits=10, decimal_places=2)
linked = models.ForeignKey(
"Child1",
on_delete=models.CASCADE,
# This is required on foreign key fields in abstract models.
# See the "Note about foreign key related names" below.
related_name="%(app_label)s_%(class)s_related",
related_query_name="%(app_label)s_%(class)ss",
)
class Meta:
abstract = True
class Child1(DescendantType1):
"""A descendant with "type 1" attributes."""
class Child2(DescendantType2):
"""A descendant with "type 2" attributes."""
class GrandChild1(DescendantType1):
intfield = models.DecimalField(...)
class GrandChild2(DescendantType2):
intfield = models.DecimalField(...)
linked = models.ForeignKey(
"GrandChild1",
on_delete=models.CASCADE,
)
Note about foreign key related names
An abstract model that has a foreign key needs to use a different related_name
and related_query_name
for each concrete model that inherits from it, otherwise the names for the reverse relationship would be the same for each subclass.
To handle this, django allows you to use template strings with the variables app_label
and class
so that the names are unique for the child model.
You can find more about this in the documentation.
Source:stackexchange.com