[Answered ]-Django change IntegerField to DecimalField on inherited model

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.

👤damon

Leave a comment