import json from bson import json_util from flask_mongoengine import MongoEngine from mongoengine.document import BaseDocument from mongoengine.fields import ListField, EmbeddedDocumentField from app.util import dict_to_camel, dict_to_snake, camel_to_snake db = MongoEngine() class QuarterDocumentBase(BaseDocument): meta = {'abstract': True} @classmethod def ignore_to_json(cls): return ['_id', '_cls'] @classmethod def ignore_from_json(cls): return ['_cls'] @classmethod def json_mapped_fields(cls): return {} @classmethod def additional_fields(cls): return [] def to_dict(self): result = json_util.loads(self.to_json()) for ignore in self.ignore_to_json(): result.pop(ignore, None) for additional in self.additional_fields(): result[additional] = getattr(self, additional, None) for prop_name in result: if hasattr(getattr(self, prop_name, None), 'to_dict'): result[prop_name] = getattr(self, prop_name).to_dict() elif isinstance(getattr(self, prop_name, None), list): result[prop_name] = [k.to_dict() if hasattr(k, 'to_dict') else k for k in getattr(self, prop_name)] for json_name, prop_name in self.json_mapped_fields().items(): result[json_name] = result.pop(prop_name, None) return result def to_camel_case(self): return dict_to_camel(self.to_dict()) @classmethod def from_camel_case(cls, json_data): if isinstance(json_data, str): json_data = json_util.loads(json_data) kwargs = dict_to_snake(json_data) result = cls._from_son(kwargs) return result @classmethod def _from_son(cls, son, _auto_dereference=True, created=False): for ignore in cls.ignore_from_json(): son.pop(ignore, None) for json_name, prop_name in cls.json_mapped_fields().items(): son[prop_name] = son.pop(json_name, None) return super()._from_son(son, _auto_dereference=_auto_dereference, created=created) class DocumentBase(db.Document, QuarterDocumentBase): meta = {'abstract': True} class EmbeddedDocumentBase(db.EmbeddedDocument, QuarterDocumentBase): meta = {'abstract': True}