def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0):
 if (max_depth and (cur_depth > max_depth)):
  return None
 index_end = (index_start + len(klass._meta.fields))
 obj = klass(*row[index_start:index_end])
 for f in klass._meta.fields:
  if (f.rel and (not f.null)):
   cached_row = get_cached_row(f.rel.to, row, index_end, max_depth, (cur_depth + 1))
   if cached_row:
    (rel_obj, index_end) = cached_row
    setattr(obj, f.get_cache_name(), rel_obj)
 return (obj, index_end)

def get_cached_row ( klass , row , index_start , max_depth = 0 , cur_depth = 0 ) : if ( max_depth and ( cur_depth > max_depth ) ) : return None index_end = ( index_start + len ( klass . _meta . fields ) ) obj = klass ( * row [ index_start : index_end ] ) for f in klass . _meta . fields : if ( f . rel and ( not f . null ) ) : cached_row = get_cached_row ( f . rel . to , row , index_end , max_depth , ( cur_depth + 1 ) ) if cached_row : ( rel_obj , index_end ) = cached_row setattr ( obj , f . get_cache_name ( ) , rel_obj ) return ( obj , index_end )
helper function that recursively returns an object with cache filled .