Django model inherit from one of several models

156 Views Asked by At

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.

1

There are 1 best solutions below

1
John Meinken On BEST ANSWER

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