Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize snake_case model fields to camelCase in django rest framework

I'm adding REST API endpoints to my existing Django application. I'm using DRF ModelSerializer. My model classes follow the pep8 naming convention and use snake_case for field names, but I need the JSON response to be in camelCase. How can I achieve that in a cross-cutting way without defining proxy fields on each of my serializers?

like image 418
Geekmard Avatar asked Jan 01 '26 06:01

Geekmard


1 Answers

You could generate a mixin that patches the .to_representation() method of all the top-level serializers:

class CamelCaseMixin:
    def to_representation(self, *args, **kwargs):
        return to_camelcase_data(super().to_representation(*args, **kwargs))

    def to_internal_value(self, data):
        return super().to_internal_value(to_snake_case_data(data))

with as helper functions to convert between camelCase and snake_case:

import re

CAMEL_REGEX = re.compile('(?<=.)_(\\w)')
SNAKE_REGEX = re.compile('(?<=[a-z])([A-Z])')


def match_upper(match):
    return match.group(1).upper()


def match_snake(match):
    return f'_{match.group(1).lower()}'


def to_camelcase(text):
    return CAMEL_REGEX.sub(match_upper, text)


def to_snake_case(text):
    return SNAKE_REGEX.sub(match_snake, text)


def to_camelcase_data(data):
    if isinstance(data, dict):
        return {to_camelcase(k): to_camelcase_data(v) for k, v in data.items()}
    elif isinstance(data, list):
        return [to_camelcase_data(datum) for datum in data]
    else:
        return data


def to_snake_case_data(data):
    if isinstance(data, dict):
        return {to_snake_case(k): to_snake_case_data(v) for k, v in data.items()}
    elif isinstance(data, list):
        return [to_snake_case_data(datum) for datum in data]
    else:
        return data

So you can define a model serializer:

class MyModelSerializer(CamelCaseMixin, serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = ['my_field1', 'my_field2']

and then plug in this as serializer for the APIViews and ViewSets.

like image 79
Willem Van Onsem Avatar answered Jan 02 '26 20:01

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!