Skip to content

Commit 8362c50

Browse files
Merge pull request #251 from phenobarbital/new-exports
avoid error confusing list of objects with foreign key objects
2 parents 229b397 + c845ef9 commit 8362c50

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

datamodel/models.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -230,15 +230,18 @@ def __collapse_as_values__(
230230
) -> dict[str, Any]:
231231
"""Recursively converts any BaseModel instances to their primary key value."""
232232
out = {}
233-
fields = self.columns()
234-
for name, field in fields.items():
233+
_fields = self.columns()
234+
for name, field in _fields.items():
235235
# datatype = field.type
236236
value = getattr(self, name)
237237
if value is None and remove_nulls:
238238
continue
239239
if isinstance(value, ModelMixin):
240240
if as_values:
241-
out[name] = getattr(value, name)
241+
try:
242+
out[name] = getattr(value, name)
243+
except AttributeError:
244+
out[name] = value.to_json()
242245
else:
243246
out[name] = value.__collapse_as_values__(
244247
remove_nulls=remove_nulls,
@@ -247,11 +250,21 @@ def __collapse_as_values__(
247250
)
248251
# if it's a list, might contain submodels or scalars
249252
elif isinstance(value, list):
253+
if field.origin is list and field.args:
254+
submodel_class = field.args[0] # The type inside the list
255+
if issubclass(
256+
submodel_class, ModelMixin
257+
) and not hasattr(submodel_class, name):
258+
out[name] = json_encoder(value)
259+
continue
250260
items_out = []
251261
for item in value:
252262
if isinstance(item, ModelMixin):
253263
if as_values:
254-
items_out.append(getattr(item, name))
264+
try:
265+
items_out.append(getattr(item, name))
266+
except AttributeError:
267+
items_out.append(item.to_json())
255268
else:
256269
items_out.append(item.__collapse_as_values__(
257270
remove_nulls=remove_nulls,
@@ -391,7 +404,7 @@ def _build_settings(cls, locale: Any = None) -> dict:
391404
@classmethod
392405
def _build_fields(cls, title: str, locale: Any = None) -> dict:
393406
"""Build the fields part of the schema."""
394-
fields = {}
407+
_fields = {}
395408
required = []
396409
defs = {}
397410

@@ -400,12 +413,12 @@ def _build_fields(cls, title: str, locale: Any = None) -> dict:
400413
field_schema, field_defs, field_required = cls._process_field_schema(
401414
name, field, locale, title
402415
)
403-
fields[name] = field_schema
416+
_fields[name] = field_schema
404417
if field_required:
405418
required.append(name)
406419
if field_defs:
407420
defs[name] = field_defs.get('schema')
408-
return fields, required, defs
421+
return _fields, required, defs
409422

410423
@classmethod
411424
def _extract_field_basics(cls, name: str, field: Field, title: str):
@@ -623,7 +636,7 @@ def schema(cls, as_dict=False, locale: Any = None):
623636
endpoint_kwargs = {"endpoint": endpoint} if endpoint else {}
624637

625638
# Build the fields part of the schema.
626-
fields, required, defs = cls._build_fields(title, locale)
639+
_fields, required, defs = cls._build_fields(title, locale)
627640

628641
base_schema = {
629642
"$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -636,7 +649,7 @@ def schema(cls, as_dict=False, locale: Any = None):
636649
"type": "object",
637650
"table": table,
638651
"schema": schema,
639-
"properties": fields,
652+
"properties": _fields,
640653
"required": required,
641654
"display_name": display_name,
642655
}

datamodel/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
'simple library based on python +3.8 to use Dataclass-syntax'
77
'for interacting with Data'
88
)
9-
__version__ = '0.10.9'
9+
__version__ = '0.10.10'
1010
__copyright__ = 'Copyright (c) 2020-2024 Jesus Lara'
1111
__author__ = 'Jesus Lara'
1212
__author_email__ = '[email protected]'

0 commit comments

Comments
 (0)