beda-software/drf-writable-nested

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

kabancheg opened this issue · 3 comments

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
    )  

same issue, but it complains about .create()

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

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.