Skip to content

Commit 70fb4c1

Browse files
authored
Merge pull request #134 from netboxlabs/fix-testing
Fix get_models for testing
2 parents 5bd261e + 6d1004a commit 70fb4c1

File tree

1 file changed

+53
-32
lines changed

1 file changed

+53
-32
lines changed

netbox_custom_objects/__init__.py

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import sys
2+
import warnings
23

34
from django.core.exceptions import AppRegistryNotReady
5+
from django.db import transaction
6+
from django.db.utils import DatabaseError, OperationalError, ProgrammingError
47
from netbox.plugins import PluginConfig
58

69

@@ -9,12 +12,32 @@ def is_running_migration():
912
Check if the code is currently running during a Django migration.
1013
"""
1114
# Check if 'makemigrations' or 'migrate' command is in sys.argv
12-
if any(cmd in sys.argv for cmd in ['makemigrations', 'migrate']):
15+
if any(cmd in sys.argv for cmd in ["makemigrations", "migrate"]):
1316
return True
1417

1518
return False
1619

1720

21+
def check_custom_object_type_table_exists():
22+
"""
23+
Check if the CustomObjectType table exists in the database.
24+
Returns True if the table exists, False otherwise.
25+
"""
26+
from .models import CustomObjectType
27+
28+
try:
29+
# Try to query the model - if the table doesn't exist, this will raise an exception
30+
# this check and the transaction.atomic() is only required when running tests as the
31+
# migration check doesn't work correctly in the test environment
32+
with transaction.atomic():
33+
# Force immediate execution by using first()
34+
CustomObjectType.objects.first()
35+
return True
36+
except (OperationalError, ProgrammingError, DatabaseError):
37+
# Catch database-specific errors (table doesn't exist, permission issues, etc.)
38+
return False
39+
40+
1841
# Plugin Configuration
1942
class CustomObjectsPluginConfig(PluginConfig):
2043
name = "netbox_custom_objects"
@@ -59,37 +82,35 @@ def get_model(self, model_name, require_ready=True):
5982

6083
return obj.get_model()
6184

62-
# def get_models(self, include_auto_created=False, include_swapped=False):
63-
# """Return all models for this plugin, including custom object type models."""
64-
# # Get the regular Django models first
65-
# for model in super().get_models(include_auto_created, include_swapped):
66-
# yield model
67-
#
68-
# # Skip custom object type model loading if running during migration
69-
# if is_running_migration():
70-
# return
71-
#
72-
# # Suppress warnings about database calls during model loading
73-
# with warnings.catch_warnings():
74-
# warnings.filterwarnings(
75-
# "ignore", category=RuntimeWarning, message=".*database.*"
76-
# )
77-
# warnings.filterwarnings(
78-
# "ignore", category=UserWarning, message=".*database.*"
79-
# )
80-
#
81-
# # Add custom object type models
82-
# from .models import CustomObjectType
83-
#
84-
# # Only load models that are already cached to avoid creating all models at startup
85-
# # This prevents the "two TaggableManagers with same through model" error
86-
# custom_object_types = CustomObjectType.objects.all()
87-
# for custom_type in custom_object_types:
88-
# # Only yield already cached models during discovery
89-
# if CustomObjectType.is_model_cached(custom_type.id):
90-
# model = CustomObjectType.get_cached_model(custom_type.id)
91-
# if model:
92-
# yield model
85+
def get_models(self, include_auto_created=False, include_swapped=False):
86+
"""Return all models for this plugin, including custom object type models."""
87+
# Get the regular Django models first
88+
for model in super().get_models(include_auto_created, include_swapped):
89+
yield model
90+
91+
# Suppress warnings about database calls during model loading
92+
with warnings.catch_warnings():
93+
warnings.filterwarnings(
94+
"ignore", category=RuntimeWarning, message=".*database.*"
95+
)
96+
warnings.filterwarnings(
97+
"ignore", category=UserWarning, message=".*database.*"
98+
)
99+
100+
# Skip custom object type model loading if running during migration
101+
if is_running_migration() or not check_custom_object_type_table_exists():
102+
return
103+
104+
# Add custom object type models
105+
from .models import CustomObjectType
106+
107+
custom_object_types = CustomObjectType.objects.all()
108+
for custom_type in custom_object_types:
109+
# Only yield already cached models during discovery
110+
if CustomObjectType.is_model_cached(custom_type.id):
111+
model = CustomObjectType.get_cached_model(custom_type.id)
112+
if model:
113+
yield model
93114

94115

95116
config = CustomObjectsPluginConfig

0 commit comments

Comments
 (0)