1

I am new to Django and was having a hard time figuring out how to structure this.

I have a base class (model) that has 2 derived classes.

These two derived classes have some common fields which I put in the base class. And each derived class has their own fields as well.

There is another class and one of the fields of this class is a foreign key. This foreign key should be one of the two derived classes.

To accept both types of classes, I used the base class as the model for the Foreign Key.

The issue with this solution is that when I serialize the data and receive the data, only the base class fields (data) is shown/ served (because the foreign key uses the base class).

How else would one structure this so that the Foreign Key can accept two or more similar derived classes?

Here is some code for some context on what I tried.

Base Class

    class SizeClassification(models.Model):
        name = models.CharField(blank=False, max_length=30)
        sizeClassificationType = models.CharField(max_length=30, choices=SizeClassificationChoice.choices())

Derived Class 1

    class SieveSizeClassification(SizeClassification):
        supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, null=True, related_name="sieveSizeClassificationsOfSupplier")
        productReferenceNumber = models.CharField(blank=True, max_length=50, null=True)

Derived Class 2

    class GemstonePropertySizeClassification(SizeClassification):
        gemstoneSizePropertyType = models.CharField(blank=True, max_length=30, null=True, choices=GemstoneSizePropertyTypeChoice.choices())
        unit = models.ForeignKey(Unit, on_delete=models.CASCADE, null=True, related_name="gemstonePropertySizeClassificationOfUnit")

Class whose Foreign Key can be one of the two derived classes

    class SizeConfiguration(models.Model):
    name = models.CharField(blank=False, max_length=30)
        sizeClassification = models.ForeignKey(SizeClassification, on_delete=models.CASCADE, null=False, related_name="sizeConfigurationsOfSizeClassifications")
        customSizeNamingTemplate = models.OneToOneField(CustomSizeNamingTemplate, on_delete=models.CASCADE, blank = False, null=False)

Base Class Serializer

    class SizeClassificationSerializer(serializers.ModelSerializer):
        class Meta:
            model = SizeClassification
            fields = ['id', 'name', 'sizeClassificationType']

Serializers of Derived Classes

    class SieveSizeClassificationSerializer(serializers.ModelSerializer):
        supplier = SupplierSerializer(many=False)
        unit = UnitSerializer(many=False)
        class Meta:
            model = SieveSizeClassification
            fields = ['id', 'name', 'sizeClassificationType', 'productReferenceNumber', 'supplier']

    class GemstonePropertySizeClassificationSerializer(serializers.ModelSerializer):
        class Meta:
            model = GemstonePropertySizeClassification
            fields = ['id', 'name', 'sizeClassificationType', 'gemstoneSizePropertyType', 'unit']

Serializer of Class that needs to use Foreign Key based on 2 or more derived classes

    class SizeConfigurationSerializer(serializers.ModelSerializer):
        customSizeNamingTemplate = CustomSizeNamingTemplateSerializer(many=False)
        customSizes = CustomSizeSerializer(many=True)
        sizeClassification = SizeClassificationSerializer(many=False)
        class Meta:
        model = SizeConfiguration
        fields = ['id', 'name', 'sizeClassification', 'customSizeNamingTemplate', 'customSizes']

After creating several instances of the derived classes (GemstonePropertySizeClassification & SieveSizeClassification), and after assigning these instances to the SizeConfiguration class, the output response when serializing the SizeConfiguration class was an object containing the data of the base SizeClassification class only. However, I would like to know which exact derived instance it was (GemstoneProperty or Sieve), and what is the associated data that is specific to the derived class. That is the desired outcome.

Thank you in advance for any help, tips, suggestions on how to approach this.

acarlstein
  • 1,799
  • 2
  • 13
  • 21
palebluedot
  • 43
  • 1
  • 8
  • I don't have time for a full answer, but this approach is really hard. The reason you only see base class fields is that you are using [multi-table inheritance](https://docs.djangoproject.com/en/2.2/topics/db/models/#multi-table-inheritance). – RishiG May 14 '19 at 00:49
  • [This SO answer](https://stackoverflow.com/a/30343863/2715819) gives one option in the case of abstract inheritance, but I would advise trying to reformulate your models so that you can combine functionality in a different way if possible. – RishiG May 14 '19 at 00:50

0 Answers0