Как сериализовать поля модели snake_case в camelCase во фреймворке django rest
Я добавляю конечные точки REST API в существующее приложение Django. Я использую DRF ModelSerializer. Мои классы моделей следуют соглашению об именовании pep8 и используют snake_case для имен полей, но мне нужно, чтобы JSON-ответ был в camelCase. Как я могу добиться этого сквозным способом, не определяя прокси-поля в каждом из моих сериализаторов?
Вы можете создать миксин, который исправляет метод .to_representation()
всех сериализаторов верхнего уровня:
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))
с вспомогательными функциями для преобразования между camelCase и 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
Так вы можете определить сериализатор модели:
class MyModelSerializer(CamelCaseMixin, serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ['my_field1', 'my_field2']
и затем подключите это в качестве сериализатора для APIView
s и ViewSet
s.