beda-software / drf-writable-nested

Writable nested model serializer for Django REST Framework
Other
1.07k stars 116 forks source link

Django polymorphic + drf writable nested. The `.update()` method does not support writable nested fields by default. #139

Open kabancheg opened 3 years ago

kabancheg commented 3 years ago

Can not update nested polymorphic object. I tried all methods (patch, put) but the drf exception occurs. I checked all issues/solutions and nothing helps. I've stucked on it for 2 weeks. Maybe I am doing wrong...

exception

The `.update()` method does not support writable nested fields by default.
Write an explicit `.update()` method for serializer `api.serializers.NodeSerializer`, or set `read_only=True` on nested serializer fields.

data

{
    "pk": 1,
    "context_set": [
        {
            "field": 1,
            "node": 1,
            "resourcetype": "SimpleContext"
        }
    ]
}

requirements

django-rest-polymorphic==0.1.9
drf-writable-nested==0.6.2
djangorestframework==3.11.1
Django==3.0

serializers.py

class SimpleContextSerializer(serializers.ModelSerializer):
    class Meta:
        model = SimpleContext
        fields = ['id', 'field', 'node']

class TemplateContextSerializer(serializers.ModelSerializer):
    class Meta:
        model = TemplateContext
        fields = ['id', 'field', 'node']

class ContextPolymorphicSerializer(PolymorphicSerializer):
    model_serializer_mapping = {
        SimpleContext: SimpleContextSerializer,
        TemplateContext: TemplateContextSerializer
    }

class NodeSerializer(UniqueFieldsMixin, NestedUpdateMixin, serializers.ModelSerializer):
    context_set = ContextPolymorphicSerializer(many=True)

    class Meta:
        model = Node
        fields = ['pk', 'context_set']

models.py

class Node(models.Model):

    name = models.CharField(max_length=256)
    user = models.ForeignKey(
        get_user_model(),
        on_delete=models.CASCADE,
        null=True,
        blank=True
    )
    parent = models.ForeignKey(
        'Node',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='child_set'
    )
    created = models.DateTimeField(
        null=True,
        blank=True,
        default=timezone.now
    )
    archived = models.DateTimeField(
        null=True,
        blank=True,
        default=None
    )

class Context(PolymorphicModel):

    name = models.CharField(max_length=256)
    service_set = models.ManyToManyField('Service')
    field = models.ForeignKey(
        'Field',
        blank=True,
        null=True,
        on_delete=models.CASCADE
    )
    node = models.ForeignKey(
        'Node',
        blank=True,
        null=True,
        on_delete=models.SET_NULL
    )  
SidWeng commented 2 years ago

same issue, but it complains about .create()

AlanNggg commented 1 year ago
class ContextPolymorphicSerializer(PolymorphicSerializer, serializers.ModelSerializer):
    model_serializer_mapping = {
        SimpleContext: SimpleContextSerializer,
        TemplateContext: TemplateContextSerializer
    }
   class Meta:
        model = SimpleContext
        fields = '__all__'

It seems that the serializer needs to inherit serializers.ModelSerializer and have Meta class.

KIC commented 5 months ago

I still get an Incorrect type Error

rest_framework.exceptions.ValidationError: {'hierarchy': [ErrorDetail(string='Incorrect type. Expected pk value, received str.', code='incorrect_type')]}

And the hierarchy is not even of type str it is dict.