API REST Python + Flask, как преобразовать ключи данных между camelcase и snakecase?

Я изучаю Python и пишу простой REST API с помощью микро-фреймворка Flask.

Я использую SQLAlchemy для объектно-реляционного отображения и Зефир для объектной сериализации / десериализации.

Я использую snakecase для своих имен переменных (согласно PEP8).

Мне нужно преобразовать ключи объекта JSON из camelcase в snakecase при получении данных из внешнего интерфейса (Angular) и наоборот, при возврате данных ответа.

Каков наилучший подход для этого с помощью Flask?

Я не смог найти хороший ответ в интернете.

1 ответ

Решение

Вы не конвертируете свои ключи, потому что вам это не нужно. Данные не являются кодом, ключи в JSON не являются переменными. Они не подлежат PEP8, и вы не конвертируете их.

Если у вас есть соглашение для ваших ключей объекта JSON, придерживайтесь его везде, в вашей передней и задней части. Тогда используйте Зефир 3.x data_key аргумент для поля, чтобы установить имя ключа в документе JSON при загрузке и выгрузке.

Например

class UserSchema(Schema):
    first_name = fields.String(data_key="firstName")
    last_name = fields.Email(data_key='lastName')

Если вы хотите автоматизировать это для всех ваших полей, вы можете предоставить свой собственный Schema.on_bind_field() реализация для генерации data_key значение из имени поля:

import re
from functools import partial

from marshmallow import Schema

_snake_case = re.compile(r"(?<=\w)_(\w)")
_to_camel_case = partial(_snake_case.sub, lambda m: m[1].upper())

class CamelCasedSchema(Schema):
    """Gives fields a camelCased data key"""
    def on_bind_field(self, field_name, field_obj, _cc=_to_camel_case):
        field_obj.data_key = _cc(field_name.lower())

Демо-версия:

>>> from marshmallow import fields
>>> class UserSchema(CamelCasedSchema):
...     first_name = fields.String()
...     last_name = fields.String()
...
>>> schema = UserSchema()
>>> schema.load({"firstName": "Eric", "lastName": "Idle"})
{'first_name': 'Eric', 'last_name': 'Idle'}
>>> schema.dump({"first_name": "John", "last_name": "Cleese"})
{'firstName': 'John', 'lastName': 'Cleese'}

Раздел примеров документации "Зефир" имеет похожий рецепт.

Если вы используете Marshmallow 2.x, то нужно установить два аргумента: load_from а также dump_to,

Другие вопросы по тегам