Set Extra Fields In Django Generic Many to Many Relationship

Wondering how I could set a generic many to many relationship including additional fields through a post request.

Note that I removed some irrelevant fields to make it easier to read. I have only included one of the objects (message) that can have these labels for simplicity.

Models

class Message(models.Model):
    text = models.CharField(max_length=250, default='text')
    labels = GenericRelation(to=Label)

class Tag(models.Model):
    color = serializers.Charfield()
    
class Label(models.Model):
    tag = models.ForeignKey(to=Tag, on_delete=models.CASCADE)

    # Generic foreign key
    object_id = models.PositiveIntegerField()
    content_type = models.ForeignKey(to=ContentType, on_delete=models.CASCADE)
    content_object = GenericForeignKey()

    confidence = models.IntegerField()
    section = models.IntegerField()

    class Meta:
        indexes = [
            models.Index(fields=["content_type", "object_id"]),
        ]

Serializers

class LabelSerializer(ModelSerializer):
    class Meta:
        model = Label
        fields = ['id', 'confidence', 'level']

class MessageSerializer(serializers.ModelSerializer):
    labels = serializers.ManyRelatedField(
        child_relation=LabelSerializer(), required=False)

    class Meta:
        model = Message
        fields = ['id', 'text', 'labels']
        

The idea would be to have the following post request to the Message api which would set the relationship between tags and messages (as well as set the message text), using the custom through table Labels with the additional fields confidence and section set.

{
 'text': 'Message Text',
 'labels': [
   {
     'tag': 1,
     'confidence': 0.9,
     'section': 1
   },
   {
     'tag': 2,
     'confidence': 0.7,
     'section': 1
   }
  ]
}

The serializer works, however the relationship/label object isn't created. Is it possible to have it automatically created like a ManyToMany relationship including the extra fields? Or would I have to override the create method in the view and manually create the labels.

Back to Top