120 lines
4.5 KiB
Python
120 lines
4.5 KiB
Python
from app import app
|
|
from flask import json
|
|
from flask_sqlalchemy import SQLAlchemy
|
|
from sqlalchemy.orm.attributes import QueryableAttribute
|
|
|
|
db = SQLAlchemy(app)
|
|
|
|
class Base(db.Model):
|
|
__abstract__ = True
|
|
|
|
def to_dict(self, show=None, _hide=[], _path=[]):
|
|
show = show or []
|
|
|
|
hidden = self._hidden_fields if hasattr(self, "_hidden_fields") else []
|
|
default = self._default_fields if hasattr(self, "_default_fields") else []
|
|
default.extend(['id', 'modified_at', 'created_at'])
|
|
|
|
hidden = self._hidden_fields if hasattr(self, "_hidden_fields") else []
|
|
default = self._default_fields if hasattr(self, "_default_fields") else []
|
|
default.extend(['id', 'modified_at', 'created_at'])
|
|
|
|
if not _path:
|
|
_path = self.__tablename__.lower()
|
|
|
|
def prepend_path(item):
|
|
item = item.lower()
|
|
if item.split(".", 1)[0] == _path:
|
|
return item
|
|
if len(item) == 0:
|
|
return item
|
|
if item[0] != ".":
|
|
item = ".%s" % item
|
|
item = "%s%s" % (_path, item)
|
|
return item
|
|
|
|
_hide[:] = [prepend_path(x) for x in _hide]
|
|
show[:] = [prepend_path(x) for x in show]
|
|
|
|
columns = self.__table__.columns.keys()
|
|
relationships = self.__mapper__.relationships.keys()
|
|
properties = dir(self)
|
|
|
|
ret_data = {}
|
|
|
|
for key in columns:
|
|
if key.startswith("_"):
|
|
continue
|
|
check = "%s.%s" % (_path, key)
|
|
if check in _hide or key in hidden:
|
|
continue
|
|
if check in show or key in default:
|
|
ret_data[key] = getattr(self, key)
|
|
|
|
for key in relationships:
|
|
if key.startswith("_"):
|
|
continue
|
|
check = "%s.%s" % (_path, key)
|
|
if check in _hide or key in hidden:
|
|
continue
|
|
if check in show or key in default:
|
|
_hide.append(check)
|
|
is_list = self.__mapper__.relationships[key].uselist
|
|
if is_list:
|
|
items = getattr(self, key)
|
|
if self.__mapper__.relationships[key].query_class is not None:
|
|
if hasattr(items, "all"):
|
|
items = items.all()
|
|
ret_data[key] = []
|
|
for item in items:
|
|
ret_data[key].append(
|
|
item.to_dict(
|
|
show=list(show),
|
|
_hide=list(_hide),
|
|
_path=("%s.%s" % (_path, key.lower())),
|
|
)
|
|
)
|
|
else:
|
|
if (
|
|
self.__mapper__.relationships[key].query_class is not None
|
|
or self.__mapper__.relationships[key].instrument_class
|
|
is not None
|
|
):
|
|
item = getattr(self, key)
|
|
if item is not None:
|
|
ret_data[key] = item.to_dict(
|
|
show=list(show),
|
|
_hide=list(_hide),
|
|
_path=("%s.%s" % (_path, key.lower())),
|
|
)
|
|
else:
|
|
ret_data[key] = None
|
|
else:
|
|
ret_data[key] = getattr(self, key)
|
|
|
|
for key in list(set(properties) - set(columns) - set(relationships)):
|
|
if key.startswith("_"):
|
|
continue
|
|
if not hasattr(self.__class__, key):
|
|
continue
|
|
attr = getattr(self.__class__, key)
|
|
if not (isinstance(attr, property) or isinstance(attr, QueryableAttribute)):
|
|
continue
|
|
check = "%s.%s" % (_path, key)
|
|
if check in _hide or key in hidden:
|
|
continue
|
|
if check in show or key in default:
|
|
val = getattr(self, key)
|
|
if hasattr(val, "to_dict"):
|
|
ret_data[key] = val.to_dict(
|
|
show=list(show),
|
|
_hide=list(_hide), _path=("%s.%s" % (_path, key.lower()))
|
|
_path = ('%s.%s' % (path, key.lower())),)
|
|
else:
|
|
try:
|
|
ret_data[key] = json.loads(json.dumps(val))
|
|
except:
|
|
pass
|
|
|
|
return ret_data
|