Я столкнулся с этой проблемой, когда пытался сохранить модель Peewee в PostgreSQL JSONField
.
После некоторой борьбы вот общее решение.
Ключ к моему решению - это прохождение исходного кода Python и осознание того, что документация по коду (описанная здесь) уже объясняет, как расширить существующий json.dumps
для поддержки других типов данных.
Предположим, у вас есть модель, которая содержит некоторые поля, не сериализуемые в JSON, а модель, содержащая поле JSON, изначально выглядит следующим образом:
class SomeClass(Model):
json_field = JSONField()
Просто определите пользовательский JSONEncoder
следующим образом:
class CustomJsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, SomeTypeUnsupportedByJsonDumps):
return < whatever value you want >
return json.JSONEncoder.default(self, obj)
@staticmethod
def json_dumper(obj):
return json.dumps(obj, cls=CustomJsonEncoder)
А затем просто используйте его в своем JSONField
, как показано ниже:
class SomeClass(Model):
json_field = JSONField(dumps=CustomJsonEncoder.json_dumper)
Ключ - это метод default(self, obj)
, описанный выше. Для каждой ... is not JSON serializable
жалобы, которую вы получаете от Python, просто добавьте код для обработки несериализуемого в JSON типа (например, Enum
или datetime
)
Например, вот как я поддерживаю класс, унаследованный от Enum
:
class TransactionType(Enum):
CURRENT = 1
STACKED = 2
def default(self, obj):
if isinstance(obj, TransactionType):
return obj.value
return json.JSONEncoder.default(self, obj)
Наконец, с кодом, реализованным, как указано выше, вы можете просто преобразовать любые модели Peewee в объект с сериализацией JSON, как показано ниже:
peewee_model = WhateverPeeweeModel()
new_model = SomeClass()
new_model.json_field = model_to_dict(peewee_model)
Хотя приведенный выше код был (в некоторой степени) специфичным для Peewee, но я думаю:
- Это применимо к другим ORM (Django и т. Д.) В целом.
- Кроме того, если вы понимаете, как работает
json.dumps
, это решение также работает с Python (без ORM) в целом.
Любые вопросы пишите в комментариях. Спасибо!
person
sivabudh
schedule
30.07.2018
import jsons
см. Ответ ниже - он отлично работает - person tswaehn   schedule 02.04.2020.to_dict()
или что-то, что может быть вызвано для объекта, прежде чем он будет передан модулю, который пытается его сериализовать. - person Felix B.   schedule 01.09.2020vars
в сочетании сjson.dumps
(см. Мой ответ stackoverflow.com/a/64469761/1587520 ) - person user1587520   schedule 23.11.2020