@@ -230,15 +230,18 @@ def __collapse_as_values__(
230
230
) -> dict [str , Any ]:
231
231
"""Recursively converts any BaseModel instances to their primary key value."""
232
232
out = {}
233
- fields = self .columns ()
234
- for name , field in fields .items ():
233
+ _fields = self .columns ()
234
+ for name , field in _fields .items ():
235
235
# datatype = field.type
236
236
value = getattr (self , name )
237
237
if value is None and remove_nulls :
238
238
continue
239
239
if isinstance (value , ModelMixin ):
240
240
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 ()
242
245
else :
243
246
out [name ] = value .__collapse_as_values__ (
244
247
remove_nulls = remove_nulls ,
@@ -247,11 +250,21 @@ def __collapse_as_values__(
247
250
)
248
251
# if it's a list, might contain submodels or scalars
249
252
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
250
260
items_out = []
251
261
for item in value :
252
262
if isinstance (item , ModelMixin ):
253
263
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 ())
255
268
else :
256
269
items_out .append (item .__collapse_as_values__ (
257
270
remove_nulls = remove_nulls ,
@@ -391,7 +404,7 @@ def _build_settings(cls, locale: Any = None) -> dict:
391
404
@classmethod
392
405
def _build_fields (cls , title : str , locale : Any = None ) -> dict :
393
406
"""Build the fields part of the schema."""
394
- fields = {}
407
+ _fields = {}
395
408
required = []
396
409
defs = {}
397
410
@@ -400,12 +413,12 @@ def _build_fields(cls, title: str, locale: Any = None) -> dict:
400
413
field_schema , field_defs , field_required = cls ._process_field_schema (
401
414
name , field , locale , title
402
415
)
403
- fields [name ] = field_schema
416
+ _fields [name ] = field_schema
404
417
if field_required :
405
418
required .append (name )
406
419
if field_defs :
407
420
defs [name ] = field_defs .get ('schema' )
408
- return fields , required , defs
421
+ return _fields , required , defs
409
422
410
423
@classmethod
411
424
def _extract_field_basics (cls , name : str , field : Field , title : str ):
@@ -623,7 +636,7 @@ def schema(cls, as_dict=False, locale: Any = None):
623
636
endpoint_kwargs = {"endpoint" : endpoint } if endpoint else {}
624
637
625
638
# 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 )
627
640
628
641
base_schema = {
629
642
"$schema" : "https://json-schema.org/draft/2020-12/schema" ,
@@ -636,7 +649,7 @@ def schema(cls, as_dict=False, locale: Any = None):
636
649
"type" : "object" ,
637
650
"table" : table ,
638
651
"schema" : schema ,
639
- "properties" : fields ,
652
+ "properties" : _fields ,
640
653
"required" : required ,
641
654
"display_name" : display_name ,
642
655
}
0 commit comments