djangorestframework-camel-case icon indicating copy to clipboard operation
djangorestframework-camel-case copied to clipboard

Ability to selectively camelize/underscorize fields

Open levic opened this issue 7 years ago • 9 comments

Some time ago I looked at using this project for converting JSON responses from underscore case to camelcase but the problem I ran into is that it doesn't distinguish between keys that are values and keys that are field names

For example:

import djangorestframework_camel_case.util as util
data = {
    'first_name': 'Mary',
    'last_name': 'Smith',
    'servers': {
        'server_west.mycompany.com': '...',
        'server_south.mycompany.com': '...',
    },
}
print(json.dumps(util.camelize(data), indent=4))

Output is:

{
    "firstName": "Mary",
    "lastName": "Smith",
    "servers": {
        "serverWest.mycompany.com": "...",
        "serverSouth.mycompany.com": "..."
    }
}

There's no way of indicating that the keys in the servers object shouldn't be modified because it's an associative array where the keys are user-supplied data.

I created an alternate implementation that adds an ignore parameter, so eg you could do the following:

util.camelize(data, ignore=['servers'])

Anything in the tree that matches the ignore specifier will be ignored (it will still recurse into that node but won't change the case on the key, and also handles arrays; ignore=['servers', 'servers.*.user_accounts'] would allow you to correctly transform something like:

{
    "first_name": "Mary",
    "last_name": "Smith",
    "servers": {
        "server_west.mycompany.com": {
            'user_accounts': {
                'mary_smith': {
                    'home_dir': '/home/mary_smith',
                },
            },
        },
    },
}

into

{
    "firstName": "Mary",
    "lastName": "Smith",
    "servers": {
        "server_west.mycompany.com": {
            'userAccounts': {
                'mary_smith': {
                    'homeDir': '/home/mary_smith',
                },
            },
        },
    },
}

If I cleaned up the code is it something that you'd be interesting in accepting a PR for or outside the scope of this project?

levic avatar Nov 02 '17 08:11 levic

@levic can you please share your camelize with ignore implementation? I have the same issue, with a JSONField. However, I am not sure that setting a global ignore pattern would work, the same key might be used in different places,

th0th avatar Mar 14 '19 21:03 th0th

I could use a feature like that too, but the other way round, so to selectively not decamelize some fields. Probably this should be defined in the serializer Meta class.

asmaps avatar Jul 17 '19 16:07 asmaps

@levic I would like to see how you have done this.

vbabiy avatar Sep 10 '19 00:09 vbabiy

I could use a feature like that too, but the other way round, so to selectively not decamelize some fields. Probably this should be defined in the serializer Meta class.

I copied the CamelCaseJSONParser class quick and dirty to use a underscoreize function which skips items in api_settings.JSON_UNDERSCOREIZE['skip_keys'].

https://gist.github.com/torfeld6/7d794b26531f0cc03043ff666980fe50

I'd like it to be in the serializer too, but I don't think it can be with a parser. It would have to be a serializer mixin.

gartmeier avatar Nov 06 '19 17:11 gartmeier

@torfeld6 This was really helpful, I modified your code slightly to handle nesting, and also created a renderer:

  • Parser: https://gist.github.com/lutrasdebtra/799faf2c8f7cb6cc80c6e41f3ef9f08e
  • Renderer: https://gist.github.com/lutrasdebtra/8be2bca78c61d1426568500503c8983c

stuart-bradley avatar Jan 07 '20 12:01 stuart-bradley

Is there a chance that a feature like that would be added to the project? I can help with something if there is space to it.

haruanm avatar May 29 '20 19:05 haruanm

I am facing the same issue, this feature would be such a great addition to the package.

dazigna avatar Jul 22 '20 15:07 dazigna

I am all for this, we just need to come up with a full PR. With docs and tests around this.

vbabiy avatar Jul 22 '20 16:07 vbabiy

Am I wrong in thinking this is possible (to some extent) through the json_underscoreize attributes of the parser/renderer classes?

sergei-maertens avatar Jan 03 '22 13:01 sergei-maertens