@@ -388,7 +388,8 @@ def get_model_field(self, field, **kwargs):
388
388
to_model = content_type .model
389
389
390
390
# Extract our custom parameters and keep only Django field parameters
391
- field_kwargs = self ._safe_kwargs (** kwargs )
391
+ generating_models = kwargs .pop ('_generating_models' , getattr (self , '_generating_models' , set ()))
392
+ field_kwargs = {k : v for k , v in kwargs .items () if not k .startswith ('_' )}
392
393
field_kwargs .update ({"default" : field .default , "unique" : field .unique })
393
394
394
395
# Handle self-referential fields by using string references
@@ -400,15 +401,35 @@ def get_model_field(self, field, **kwargs):
400
401
)
401
402
custom_object_type = CustomObjectType .objects .get (pk = custom_object_type_id )
402
403
403
- model_name = f"{ APP_LABEL } .{ custom_object_type .get_table_model_name (custom_object_type .id )} "
404
- f = LazyForeignKey (
405
- model_name ,
406
- null = True ,
407
- blank = True ,
408
- on_delete = models .CASCADE ,
409
- ** field_kwargs
410
- )
411
- return f
404
+ # Check if this is a self-referential field
405
+ if custom_object_type .id == field .custom_object_type .id :
406
+ # For self-referential fields, use LazyForeignKey to defer resolution
407
+ model_name = f"{ APP_LABEL } .{ custom_object_type .get_table_model_name (custom_object_type .id )} "
408
+ f = LazyForeignKey (
409
+ model_name ,
410
+ null = True ,
411
+ blank = True ,
412
+ on_delete = models .CASCADE ,
413
+ ** field_kwargs
414
+ )
415
+ return f
416
+ else :
417
+ # For cross-referential fields, use skip_object_fields to avoid infinite loops
418
+ # Check if we're in a recursion situation using the parameter or stored attribute
419
+ if generating_models and custom_object_type .id in generating_models :
420
+ # We're in a circular reference, don't call get_model() to prevent recursion
421
+ # Use a string reference instead
422
+ model_name = f"{ APP_LABEL } .{ custom_object_type .get_table_model_name (custom_object_type .id )} "
423
+ f = models .ForeignKey (
424
+ model_name ,
425
+ null = True ,
426
+ blank = True ,
427
+ on_delete = models .CASCADE ,
428
+ ** field_kwargs
429
+ )
430
+ return f
431
+ else :
432
+ model = custom_object_type .get_model (skip_object_fields = True )
412
433
else :
413
434
# to_model = content_type.model_class()._meta.object_name
414
435
to_ct = f"{ content_type .app_label } .{ to_model } "
0 commit comments