JSON エンコーディング#

オブジェクトが JSON にエンコードされ、JSON からデコードされる方法を制御できるようにすることがよくあります。Quart では、JSONProvider を介してこれが可能になります。

金銭の例#

例として、Money オブジェクトについて考えてみましょう。

class Money:

    def __init__(self, amount: Decimal, currency: str) -> None:
        self.amount = amount
        self.currency = currency

次のように JSON に変換します。

{
  "amount": "10.00",
  "currency": "GBP"
}

エンコーダとデコーダを使用すると次のようになります。

from quart.json.provider import _default, DefaultJSONProvider


class MoneyJSONProvider(DefaultJSONProvider):

    @staticmethod
    def default(object_):
        if isinstance(object_, date):
            return http_date(object_)
        if isinstance(object_, (Decimal, UUID)):
            return str(object_)
        if is_dataclass(object_):
            return asdict(object_)
        if hasattr(object_, "__html__"):
            return str(object_.__html__())
        if isinstance(object_, Money):
            return {'amount': object_.amount, 'currency': object_.currency}

        raise TypeError(f"Object of type {type(object_).__name__} is not JSON serializable")

    @staticmethod
    def dict_to_object(dict_):
        if 'amount' in dict_ and 'currency' in dict_:
            return Money(Decimal(dict_['amount']), dict_['currency'])
        else:
            return dict_

    def loads(self, object_, **kwargs):
        return super().loads(object_, object_hook=self.dict_to_object, **kwargs)