Skip to content

All attribute value keys inflected with underscore in parser #313

Closed
@jblakeman

Description

@jblakeman

Currently, JSONParser inflects all attribute value keys to underscore recursively. This leads to undesired behavior for JSONField or DictField serializer fields. For these fields, all of the keys in the field's object value will also be converted from uppercase to lowercase. This is restrictive behavior if one needs to do something like validate the value keys of these fields.

Consider a scenario similar to the following with JSONParser as the default parser:

class ExampleSerializer(serializers.ModelSerializer):
    json_field = serializers.JSONField()

    def validate_json_field(self, json_field):
        required_key = 'UPPERCASE_KEY'
        if required_key not in json_field:
            raise serializers.ValidationError(
                "{} key is required in json_field".format(
                    required_key
                )
            )

    # Meta defined here


class ExampleViewSet(viewsets.ModelViewSet):
    def create(self, request, *args, **kwargs):
        """
        request.data has already been modified by the parser to
        have all value keys inflected to underscore.
        So, a request like:
            {
                'data': {
                    'type': 'example_model',
                    'attributes': {
                        'json_field': {
                            "UPPERCASE_KEY": "example string"
                        }
                    }
                }
            }

        will have modified `json_field` to now be:
            {
                "uppercase_key": "example string"
            }
        """
        serializer = ExampleSerializer(data=request.data)
        # The following will raise an exception because
        # json_field's keys have all been converted to lowercase.
        serializer.is_valid(raise_exception=True)
        

I understand the desire to format some top-level or foreign key attribute keys using inflection, but am wondering if there's a reason we need to enforce the inflection of all attribute value keys to underscore (and lowercase) recursively.

Of course, the problem in this example wouldn't be present if inflection.underscore didn't convert to lowercase, but I don't think any sort of modification of the attribute value keys should be performed on anything other than the top-level or relationship value keys.

Maybe a separate settings constant like JSON_API_ATTRIBUTE_VALUE_KEYS_FORMAT can be considered? In order to fix, parse_attributes and format_keys may need to be re-written to consider top-level or related attributes only?

Will try to find time to submit a fix PR with tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions