Как сериализовать поля модели 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']

и затем подключите это в качестве сериализатора для APIViews и ViewSets.

Вернуться на верх