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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With