@@ -38,8 +38,13 @@ def model_to_identifier(instance: models.Model) -> str:
3838 return f"mdl:{ instance ._meta .app_label } :{ instance ._meta .model_name } :{ instance .pk } "
3939
4040
41+ def is_identifier (identifier : str ) -> bool :
42+ """Check if the given string is a valid model identifier."""
43+ return isinstance (identifier , str ) and identifier .startswith ("mdl:" ) and len (identifier .split (":" )) == 4
44+
45+
4146def identifier_to_model (identifier : str ) -> models .Model | None :
42- if not identifier . startswith ( "mdl:" ):
47+ if not is_identifier ( identifier ):
4348 raise ValueError (f"Invalid model identifier: { identifier } " )
4449
4550 with contextlib .suppress (ValueError , LookupError , ObjectDoesNotExist ):
@@ -220,12 +225,18 @@ def json_to_simplenamespace(model_data: dict[str, dict[str, typing.Any]], key: s
220225 # link identifiers in resolved models to their SimpleNamespace instances
221226 for resolved_model in resolved_models .values ():
222227 for attr_name , attr_value in resolved_model .__dict__ .items ():
223- if isinstance (attr_value , str ) and attr_value .startswith ("mdl:" ):
224- setattr (resolved_model , attr_name , resolved_models [attr_value ])
225- elif isinstance (attr_value , list ) and all (
226- isinstance (item , str ) and item .startswith ("mdl:" ) for item in attr_value
227- ):
228- resolved_many_rel_models = [resolved_models [item ] for item in attr_value ]
228+ if is_identifier (attr_value ):
229+ if not (resolved_instance := resolved_models .get (attr_value )):
230+ resolved_instance = identifier_to_model (attr_value )
231+ setattr (resolved_model , attr_name , resolved_instance )
232+ elif isinstance (attr_value , list ) and all (is_identifier (item ) for item in attr_value ):
233+ resolved_many_rel_models = []
234+ for item in attr_value :
235+ if not (resolved_instance := resolved_models .get (item )):
236+ resolved_instance = identifier_to_model (item )
237+ if not resolved_instance :
238+ raise ValueError (f"Related model not found for identifier: { item } " )
239+
229240 setattr (resolved_model , attr_name , resolved_many_rel_models )
230241
231242 return resolved_models [key ]
@@ -240,12 +251,12 @@ def apply_diff_to_model(models_data: dict[str, dict[str, typing.Any]]) -> list[m
240251
241252 # Apply the data to the model instance
242253 for field_name , value in model_data .items ():
243- if isinstance (value , str ) and value . startswith ( "mdl:" ):
254+ if is_identifier (value ):
244255 # If the value is a model identifier, resolve it to a model instance
245256 if not (related_model_instance := identifier_to_model (value )):
246257 raise ValueError (f"Related model not found for identifier: { value } " )
247258 setattr (model_instance , field_name , related_model_instance )
248- elif isinstance (value , list ) and all (isinstance (item , str ) and item . startswith ( "mdl:" ) for item in value ):
259+ elif isinstance (value , list ) and all (is_identifier (item ) for item in value ):
249260 # If the value is a list of model identifiers, resolve them to model instances
250261 related_model_instances = [identifier_to_model (item ) for item in value ]
251262 if None in related_model_instances :
0 commit comments