Adding fields to model upon creation of another model

I have two models one is called ChairModel and the other InventoryModel. What I want is, when I instantiate new ChairModel to automatically create a new field in the InventoryModel instance. So for example, if instance of ChairModel has attribute model_name = “Django” I want to automatically create a field in a InventoryModel that would be like this django = models.FloatField(default=0). Basically I want to add new field to InventoryModel instance every time a new ChairModel instance is created. I am beginner in django and don’t even know is this possible. I have tried with creating signals.py file and importing it in ready() method in apps.py, but it didn’t work. So, if anyone can explain how to do this and is it even possible I would be thankful.

This is ChairModel:

class ChairModel(models.Model):
    model_name = models.CharField(max_length=100)
    model_price = models.FloatField()
    model_photo = models.ImageField(default='default_chair_pic.jpg', upload_to='chair_pics')
    pedestal_type = models.ForeignKey(PedestalModel, on_delete=models.PROTECT)
    pedestal_material = models.CharField(max_length=100, choices=PEDESTAL_MATERIAL_CHOICES)
    pedestal_color = models.CharField(max_length=100)
    stretcher = models.IntegerField(default=0)
    rotating_mechanism = models.BooleanField(null=True, blank=True)
    wheels = models.BooleanField(null=True, blank=True)
    canvas_pattern = models.ForeignKey(CanvasPatterns, on_delete=models.PROTECT)
    time_to_make = models.IntegerField()
    seat_foam_needed = models.FloatField()
    steel_needed = models.FloatField(null=True, blank=True)
    wood_needed = models.FloatField(null=True, blank=True)
    canvas_needed = models.FloatField()
    thread_needed = models.FloatField()
    additional_info = models.TextField(null=True, blank=True)

This is the InventoryModel:

class InventoryModel(models.Model):
    metal_quantity = models.FloatField()
    seat_foam_quantity = models.FloatField()
    wood_quantity = models.FloatField()

    def __str__(self):
        return "Skladiste"

This is the signals.py:

from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import ChairModel, PedestalModel, InventoryModel
from django.db import models


@receiver(post_save, sender=PedestalModel)
def create_inventory_field_pedestal(sender, instance, created, **kwargs):
    if created:
        field_name = instance.pedestal_name.lower().replace(' ', '_').replace('-', '_')
        field = models.FloatField(default=0)
        InventoryModel.add_to_class(field_name, field)


@receiver(post_save, sender=ChairModel)
def create_inventory_field_chair(sender, instance, created, **kwargs):
    if created:
        field_name = instance.model_name.lower().replace(' ', '_').replace('-', '_')
        field = models.FloatField(default=0)
        InventoryModel.add_to_class(field_name, field)

This is not possible within Django, and generally speaking, is a bad design idea from a database perspective regardless of the language, framework, or database being used.

I think you need to rethink your data models, and perhaps spend some time reading about how to design database tables in a relational database

1 Like

Ok, thank you for the answer. I will try to do it in some other way.