Best approach to split one model into 3 related ones

Hi all, I hope this is the right place to ask questions about using Django, if not, please point me in the right direction, I would appreciate it :slight_smile:

I have a django application and it has a model that looks like this:

class Addon(models.Model):
    class AddonEpic(models.TextChoices):
        CONDO_CLEANING = "condo_cleaning"
        HOUSE_CLEANING = "house_cleaning"
        DRY_CLEANING = "dry_cleaning"

    class AddonType(models.TextChoices):
        SINGLE = "single"
        MULTIPLE = "multiple"

    label = models.CharField(max_length=128, null=False)
    type = models.CharField(choices=AddonType.choices, null=False)
    epic = models.CharField(choices=AddonEpic.choices, null=False)
    price = models.DecimalField(max_digits=10, decimal_places=2, null=False)
    duration = models.DecimalField(max_digits=6, decimal_places=2, null=False)
    needs_additional_data = models.BooleanField(null=False)
    icon = models.CharField(max_length=128, null=True)
    groups = models.ManyToManyField(AddonGroup)

It worked perfectly with DRF, but now the business requirements evolved, and I need to add additional fields to the model depending on the epic. For example, there should be a CondoCleaningAddon with field is_included_in_general_cleaning.

What would the easiest/most sustainable/most pythonic approach be? I considered leaving the addon model as is and creating child models CondoCleaningAddon, HouseCleaningAddon and DryCleaningAddon. Another thought was to create CondoCleaningAddonDetails and so on, and use either contenttypes or inheritance with AddonDetails base class. But due to lack of experience I find it hard to see the longer term implications of each decision, hoping someone can advise. Thank you!

Hey there!
You have some options, i would give some of mine:

Depending on the quantity of fields i would have to add, i would add them directly to the Addon class, and make them nullable or have some default. And i would create a proxy model for each of the add on classes. This would help me create a different clean method for each specific case.
Some questions you should make before choosing this: Are going to be several new epic add-ons that may increase this model size even more? If so, i would not choose this one.

You can create a JSONField and have each epic control which fields will be there, and how to use them.
Some questions you should make before choosing this: Are this fields going to be heavily queried by? If so, you may want to get familiar with JSONField queries, and your database-vendor specifics on storing it, like postgres.

Your suggestion may also work, but i can’t give you any specific advice on this implementation.

Hope this helps you find an answer!

1 Like

There is no single “best” way to approach this. It’s highly unlikely that anyone here is going to know your potential future requirements and what you may need to add or change in the future.

In the general case, you’re going to be able to make pretty much any approach work.

Side note: I tend to think about this in terms of relational data modelling and not with reference to any specific language or framework. I start by creating a set of normalized tables and then implement the models to match.