djangodjango-modelsdjango-inheritance

Django model inherit from one of several models


I am new in Django an have trouble figuring out the right way of making model inheritance.

Let assume that I am making some kind of food app. I would then have a model for meet, a model for fruit, a model for vegetables and so on.

My question is: How can I make a nutrition content model, which can inherit from all of the above models but only from one at a time? For instance nutrition content of apple should only inherit from the fruit model.

If there was only one food model type I would use ForeignKey to handle the inheritance. I guess this is not an option when there are several options for models to inherit from.

I would like to use on_delete=models.CASCADE for the nutrition content model. Hence the request for inheritance.

Any suggestions will be appreciated.


Solution

  • Python class inheritance and Django model ForeignKey relationships are two completely different things. It sounds like you're referring to the latter.

    Are the fields so different between the different food types that you actually need a different model for each one? The simplest way would be to just have single Food model for all food types.

    class Food(models.model):
        VEGETABLE = 'vegetable'
        MEAT = 'meat'
        FRUIT = 'fruit'
        TYPE_CHOICES = [
            (VEGETABLE, 'vegetable'),
            (MEAT, 'meat'),
            (FRUIT, 'fruit'),
        ]
        type = models.CharField(max_length=10, choices=TYPE_CHOICES)
        nutrition_content = models.OneToOneField('NutritionContent', on_delete=models.CASCADE)
        # additional fields
    
    class NutritionContent(models.Model):
        # additional fields
    

    If your fields are so different between food types that you need to have different models for each one, you can set up Food as a parent model that all child food type models have a OneToOneField relationship with. Then the NutritionContent model can still link with Food.

    class Food(models.model):
        nutrition_content = models.OneToOneField('NutritionContent', on_delete=models.CASCADE)
        # fields that apply to all foods
    
    class Vegetable(models.Model):
       food = models.OneToOneField('Food', on_delete=models.CASCADE)
       # additional fields that only apply to vegetables
    
    class Meat(models.Model):
       food = models.OneToOneField('Food', on_delete=models.CASCADE)
       # additional fields that only apply to meat
    
    class Fruit(models.Model):
       food = models.OneToOneField('Food', on_delete=models.CASCADE)
       # additional fields that only apply to fruit
    
    class NutritionContent(models.Model):
        # additional fields