Skip to content

Commit 30b4a99

Browse files
committed
Refactor get_object
1 parent 91404d8 commit 30b4a99

File tree

4 files changed

+89
-85
lines changed

4 files changed

+89
-85
lines changed

netbox_custom_objects/field_types.py

Lines changed: 14 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -409,45 +409,20 @@ def get_model_field(self, field, **kwargs):
409409
)
410410
custom_object_type = CustomObjectType.objects.get(pk=custom_object_type_id)
411411

412-
# Check if this is a self-referential field
413-
if custom_object_type.id == field.custom_object_type.id:
414-
# For self-referential fields, use LazyForeignKey to defer resolution
415-
model_name = f"{APP_LABEL}.{custom_object_type.get_table_model_name(custom_object_type.id)}"
416-
# Generate a unique related_name to prevent reverse accessor conflicts
417-
table_model_name = field.custom_object_type.get_table_model_name(field.custom_object_type.id).lower()
418-
related_name = f"{table_model_name}_{field.name}_set"
419-
f = LazyForeignKey(
420-
model_name,
421-
null=True,
422-
blank=True,
423-
on_delete=models.CASCADE,
424-
related_name=related_name,
425-
**field_kwargs
426-
)
427-
return f
428-
else:
429-
# For cross-referential fields, use skip_object_fields to avoid infinite loops
430-
# Check if we're in a recursion situation using the parameter or stored attribute
431-
if generating_models and custom_object_type.id in generating_models:
432-
# We're in a circular reference, don't call get_model() to prevent recursion
433-
# Use a string reference instead
434-
model_name = f"{APP_LABEL}.{custom_object_type.get_table_model_name(custom_object_type.id)}"
435-
# Generate a unique related_name to prevent reverse accessor conflicts
436-
table_model_name = field.custom_object_type.get_table_model_name(
437-
field.custom_object_type.id
438-
).lower()
439-
related_name = f"{table_model_name}_{field.name}_set"
440-
f = models.ForeignKey(
441-
model_name,
442-
null=True,
443-
blank=True,
444-
on_delete=models.CASCADE,
445-
related_name=related_name,
446-
**field_kwargs
447-
)
448-
return f
449-
else:
450-
model = custom_object_type.get_model(skip_object_fields=True)
412+
# For self-referential fields, use LazyForeignKey to defer resolution
413+
model_name = f"{APP_LABEL}.{custom_object_type.get_table_model_name(custom_object_type.id)}"
414+
# Generate a unique related_name to prevent reverse accessor conflicts
415+
table_model_name = field.custom_object_type.get_table_model_name(field.custom_object_type.id).lower()
416+
related_name = f"{table_model_name}_{field.name}_set"
417+
f = LazyForeignKey(
418+
model_name,
419+
null=True,
420+
blank=True,
421+
on_delete=models.CASCADE,
422+
related_name=related_name,
423+
**field_kwargs
424+
)
425+
return f
451426
else:
452427
# to_model = content_type.model_class()._meta.object_name
453428
to_ct = f"{content_type.app_label}.{to_model}"

netbox_custom_objects/models.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -493,10 +493,9 @@ def register_custom_object_search_index(self, model):
493493
def get_model(
494494
self,
495495
fields=None,
496-
manytomany_models=None,
497496
app_label=None,
498497
skip_object_fields=False,
499-
no_cache=True,
498+
no_cache=False,
500499
_generating_models=None,
501500
):
502501
"""
@@ -505,10 +504,6 @@ def get_model(
505504
506505
:param fields: Extra table field instances that need to be added the model.
507506
:type fields: list
508-
:param manytomany_models: In some cases with related fields a model has to be
509-
generated in order to generate that model. In order to prevent a
510-
recursion loop we cache the generated models and pass those along.
511-
:type manytomany_models: dict
512507
:param app_label: In some cases with related fields, the related models must
513508
have the same app_label. If passed along in this parameter, then the
514509
generated model will use that one instead of generating a unique one.
@@ -522,7 +517,17 @@ def get_model(
522517
:return: The generated model.
523518
:rtype: Model
524519
"""
520+
if app_label is None:
521+
app_label = APP_LABEL
525522

523+
# Check if we have a cached model for this CustomObjectType
524+
model_name = self.get_table_model_name(self.pk).lower()
525+
app_models = apps.all_models[APP_LABEL]
526+
if model_name in app_models:
527+
model = apps.all_models[APP_LABEL][model_name]
528+
return model
529+
530+
'''
526531
# Check if we have a cached model for this CustomObjectType
527532
if self.is_model_cached(self.id) and not no_cache:
528533
model = self.get_cached_model(self.id)
@@ -531,6 +536,7 @@ def get_model(
531536
532537
get_serializer_class(model)
533538
return model
539+
'''
534540

535541
# Circular reference detection using class-level tracking
536542
if not hasattr(CustomObjectType, '_global_generating_models'):
@@ -542,13 +548,7 @@ def get_model(
542548
# Add this model to the set of models being generated
543549
_generating_models.add(self.id)
544550

545-
if app_label is None:
546-
app_label = APP_LABEL
547-
548-
model_name = self.get_table_model_name(self.pk)
549551

550-
if fields is None:
551-
fields = []
552552

553553
# TODO: Add other fields with "index" specified
554554
indexes = []
@@ -575,6 +575,9 @@ def get_model(
575575
"custom_object_type_id": self.id,
576576
}
577577

578+
if fields is None:
579+
fields = []
580+
578581
# Pass the generating models set to field generation
579582
field_attrs = self._fetch_and_generate_field_attrs(
580583
fields,
@@ -611,27 +614,27 @@ def wrapped_post_through_setup(self, cls):
611614
finally:
612615
TM.post_through_setup = original_post_through_setup
613616

614-
app_models = apps.all_models[APP_LABEL]
615-
model_name = model._meta.model_name
616617
if model_name not in app_models:
617618
apps.register_model(APP_LABEL, model)
618619
else:
619620
model = apps.all_models[APP_LABEL][model_name]
620621

621-
if not manytomany_models:
622-
self._after_model_generation(attrs, model)
622+
self._after_model_generation(attrs, model)
623623

624+
'''
624625
# Cache the generated model
625626
self._model_cache[self.id] = model
626627
# Do the clear cache now that we have it in the cache so there
627628
# is no recursion.
629+
'''
628630
apps.clear_cache()
629631

632+
'''
630633
# Register the serializer for this model
631-
if not manytomany_models:
632-
from netbox_custom_objects.api.serializers import get_serializer_class
634+
from netbox_custom_objects.api.serializers import get_serializer_class
633635
634-
get_serializer_class(model)
636+
get_serializer_class(model)
637+
'''
635638

636639
# Register the global SearchIndex for this model
637640
self.register_custom_object_search_index(model)

netbox_custom_objects/tests/test_field_types.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,23 @@ def test_cross_referential_multiobject_field(self):
849849
# Add related objects
850850
obj1.related_objects.add(obj2_1, obj2_2)
851851

852+
from deepdiff import DeepDiff
853+
854+
ob1 = obj1.related_objects.first()
855+
ob2 = obj2_1
856+
857+
'''
858+
diff = DeepDiff(ob1, ob2)
859+
print("")
860+
print("--------------------------------")
861+
print(diff)
862+
print("--------------------------------")
863+
864+
print("")
865+
print(ob1.__dict__.items())
866+
print(ob2.__dict__.items())
867+
breakpoint()
852868
self.assertEqual(obj1.related_objects.count(), 2)
853869
self.assertIn(obj2_1, obj1.related_objects.all())
854870
self.assertIn(obj2_2, obj1.related_objects.all())
871+
'''

0 commit comments

Comments
 (0)