@@ -229,15 +229,6 @@ def clear_model_cache(cls, custom_object_type_id=None):
229
229
# Clear Django apps registry cache to ensure newly created models are recognized
230
230
apps .get_models .cache_clear ()
231
231
232
- # Clear global recursion tracking when clearing cache
233
- cls .clear_global_recursion_tracking ()
234
-
235
- @classmethod
236
- def clear_global_recursion_tracking (cls ):
237
- """Clear the global recursion tracking set."""
238
- if hasattr (cls , '_global_generating_models' ):
239
- cls ._global_generating_models .clear ()
240
-
241
232
@classmethod
242
233
def get_cached_model (cls , custom_object_type_id ):
243
234
"""
@@ -314,7 +305,6 @@ def _fetch_and_generate_field_attrs(
314
305
self ,
315
306
fields ,
316
307
skip_object_fields = False ,
317
- generating_models = None ,
318
308
):
319
309
field_attrs = {
320
310
"_primary_field_id" : - 1 ,
@@ -338,17 +328,10 @@ def _fetch_and_generate_field_attrs(
338
328
field_type = FIELD_TYPE_CLASS [field .type ]()
339
329
field_name = field .name
340
330
341
- # Pass generating models set to field generation to prevent infinite loops
342
- field_type ._generating_models = generating_models
343
-
344
331
# Check if we're in a recursion situation before generating the field
345
332
# Use depth-based recursion control: allow self-referential fields at level 0, skip at deeper levels
346
333
should_skip = False
347
334
348
- # Calculate depth correctly: depth 0 is when we're generating the main model
349
- # depth 1+ is when we're generating related models recursively
350
- current_depth = len (generating_models ) - 1 if generating_models else 0
351
-
352
335
if field .type in [CustomFieldTypeChoices .TYPE_OBJECT , CustomFieldTypeChoices .TYPE_MULTIOBJECT ]:
353
336
if field .related_object_type :
354
337
# Check if this field references the same CustomObjectType (self-referential)
@@ -366,23 +349,8 @@ def _fetch_and_generate_field_attrs(
366
349
if id_match :
367
350
custom_object_type_id = int (id_match .group (1 ))
368
351
369
- if custom_object_type_id == self .id :
370
- # This is a self-referential field
371
- if current_depth == 0 :
372
- # At level 0, allow self-referential fields
373
- should_skip = False
374
- else :
375
- # At deeper levels, skip self-referential fields to prevent infinite recursion
376
- should_skip = True
377
-
378
- if should_skip :
379
- # Skip this field to prevent further recursion
380
- field_attrs ["_skipped_fields" ].add (field .name )
381
- continue
382
-
383
352
field_attrs [field .name ] = field_type .get_model_field (
384
353
field ,
385
- _generating_models = generating_models , # Pass as prefixed parameter
386
354
)
387
355
388
356
# Add to field objects only if the field was successfully generated
@@ -493,7 +461,6 @@ def register_custom_object_search_index(self, model):
493
461
def get_model (
494
462
self ,
495
463
skip_object_fields = False ,
496
- _generating_models = None ,
497
464
):
498
465
"""
499
466
Generates a temporary Django model based on available fields that belong to
@@ -503,8 +470,6 @@ def get_model(
503
470
:type fields: list
504
471
:param skip_object_fields: Don't add object or multiobject fields to the model
505
472
:type skip_object_fields: bool
506
- :param _generating_models: Internal parameter to track models being generated
507
- :type _generating_models: set
508
473
:return: The generated model.
509
474
:rtype: Model
510
475
"""
@@ -514,16 +479,6 @@ def get_model(
514
479
model = self .get_cached_model (self .id )
515
480
return model
516
481
517
- # Circular reference detection using class-level tracking
518
- if not hasattr (CustomObjectType , '_global_generating_models' ):
519
- CustomObjectType ._global_generating_models = set ()
520
-
521
- if _generating_models is None :
522
- _generating_models = CustomObjectType ._global_generating_models
523
-
524
- # Add this model to the set of models being generated
525
- _generating_models .add (self .id )
526
-
527
482
model_name = self .get_table_model_name (self .pk )
528
483
529
484
# TODO: Add other fields with "index" specified
@@ -556,7 +511,6 @@ def get_model(
556
511
field_attrs = self ._fetch_and_generate_field_attrs (
557
512
fields ,
558
513
skip_object_fields = skip_object_fields ,
559
- generating_models = _generating_models
560
514
)
561
515
562
516
attrs .update (** field_attrs )
@@ -589,9 +543,9 @@ def wrapped_post_through_setup(self, cls):
589
543
TM .post_through_setup = original_post_through_setup
590
544
591
545
# Register the main model with Django's app registry
592
- if model_name in apps .all_models [APP_LABEL ]:
546
+ if model_name . lower () in apps .all_models [APP_LABEL ]:
593
547
# Remove the existing model from all_models before registering the new one
594
- del apps .all_models [APP_LABEL ][model_name ]
548
+ del apps .all_models [APP_LABEL ][model_name . lower () ]
595
549
596
550
apps .register_model (APP_LABEL , model )
597
551
'''
@@ -613,6 +567,7 @@ def wrapped_post_through_setup(self, cls):
613
567
# Do the clear cache now that we have it in the cache so there
614
568
# is no recursion.
615
569
apps .clear_cache ()
570
+ ContentType .objects .clear_cache ()
616
571
617
572
'''
618
573
# Register the serializer for this model
@@ -624,16 +579,6 @@ def wrapped_post_through_setup(self, cls):
624
579
# Register the global SearchIndex for this model
625
580
self .register_custom_object_search_index (model )
626
581
627
- # Clean up: remove this model from the set of models being generated
628
- if _generating_models is not None :
629
- _generating_models .discard (self .id )
630
- # Also clean up from global tracking if this is the global set
631
- if _generating_models is CustomObjectType ._global_generating_models :
632
- CustomObjectType ._global_generating_models .discard (self .id )
633
- # Clear global tracking when we're done to ensure clean state
634
- if len (CustomObjectType ._global_generating_models ) == 0 :
635
- CustomObjectType ._global_generating_models .clear ()
636
-
637
582
return model
638
583
639
584
def create_model (self ):
0 commit comments