django-restql icon indicating copy to clipboard operation
django-restql copied to clipboard

Can not replace JSONField with a custom Serializer

Open dnievas04 opened this issue 4 years ago • 3 comments
trafficstars

I have the following serializer:

class ProductSerializer(NestedModelSerializer):
    persons = NestedField(PersonSerializer, required=True, many=True)
    attributes = serializers.JSONField()

but when I try to change the attributes field with a new serializer like this.

class ProductAttributesSerializer(serializers.Serializer):
    volume= serializers.FloatField(required=True)
    volume_units = serializers.FloatField(required=True)

class ProductSerializer(NestedModelSerializer):
    persons = NestedField(PersonSerializer, required=True, many=True)
    attributes = ProductAttributesSerializer(required=True)

I get an error when trying to create new objects.

I get the following error:

AssertionError at /api/v2/product/ The .create() method does not support writable nested fields by default. Write an explicit .create() method for serializer serializers.ProductSerializer, or set read_only=True` on nested serializer fields.

Any ideas on how can I could fix this? Thanks

dnievas04 avatar Sep 08 '21 21:09 dnievas04

You should use NestedField on your attributes field too, like

class ProductSerializer(NestedModelSerializer):
    persons = NestedField(PersonSerializer, required=True, many=True)
    attributes = NestedField(ProductAttributesSerializer, required=True, many=True)

yezyilomo avatar Sep 08 '21 23:09 yezyilomo

Hey @yezyilomo thanks for your answer. I tried your example, but after declaring the field as a NestedField, I was asked to add the Meta attribute.

AttributeError: type object 'ProductAttributesSerializer' has no attribute 'Meta'

Remember that my serializer is trying to replace a JSONField, so it is not associated with any particular model. However for testing purposes I added the meta class like this:

class ProductAttributesSerializer(serializers.Serializer):
    volume_of_solution_prepared = serializers.FloatField(required=True)
    volume_units = serializers.FloatField(required=True)

    class Meta:
        fields = ('volume_of_solution_prepared', 'volume_units')

After trying to create a new object I got the following error again:

NotImplementedError at /api/v2/product/ create() must be implemented.

Any other ideas? I would appreciate any help! Thanks

dnievas04 avatar Sep 09 '21 01:09 dnievas04

If attributes is not a nested field, why would you need to replace it with a serializer, I guess my question is when user pass product attributes (volume_of_solution_prepared, volume_units) what do you do with them, or where do they go? aren’t they associated with Product model?, What’s the relationship between Product and ProductAttributes on your models?

yezyilomo avatar Sep 09 '21 05:09 yezyilomo