Skip to content

Commit ad8c41b

Browse files
committed
#342 update init to use migration graph instead of filename
1 parent 791b42b commit ad8c41b

File tree

1 file changed

+50
-14
lines changed

1 file changed

+50
-14
lines changed

netbox_custom_objects/__init__.py

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import warnings
44

55
from django.db import connection, transaction
6+
from django.db.migrations.loader import MigrationLoader
67
from django.db.migrations.recorder import MigrationRecorder
78
from django.db.models.signals import pre_migrate, post_migrate
89
from django.db.utils import DatabaseError, OperationalError, ProgrammingError
@@ -13,9 +14,9 @@
1314
# Context variable to track if we're currently running migrations
1415
_is_migrating = contextvars.ContextVar('is_migrating', default=False)
1516

16-
# Minimum migration required for the plugin to function properly
17-
# Update this when adding migrations that add fields to the plugin's models
18-
REQUIRED_MIGRATION = '0003_ensure_fk_constraints'
17+
# Cache for migration check to avoid repeated expensive filesystem/database operations
18+
_migrations_checked = None
19+
_checking_migrations = False
1920

2021

2122
def _migration_started(sender, **kwargs):
@@ -24,8 +25,11 @@ def _migration_started(sender, **kwargs):
2425

2526

2627
def _migration_finished(sender, **kwargs):
27-
"""Signal handler for post_migrate - clears the migration flag."""
28+
"""Signal handler for post_migrate - clears the migration flag and cache."""
29+
global _migrations_checked
2830
_is_migrating.set(False)
31+
# Clear the cache after migrations run so we check again
32+
_migrations_checked = None
2933

3034

3135
# Plugin Configuration
@@ -54,10 +58,12 @@ def _should_skip_dynamic_model_creation():
5458
Returns True if dynamic models should not be created/loaded due to:
5559
- Currently running migrations
5660
- Running tests
57-
- Required migration not yet applied
61+
- All migrations not yet applied
5862
5963
Returns False if it's safe to proceed with dynamic model creation.
6064
"""
65+
global _migrations_checked, _checking_migrations
66+
6167
# Skip if currently running migrations
6268
if _is_migrating.get():
6369
return True
@@ -66,17 +72,47 @@ def _should_skip_dynamic_model_creation():
6672
if "test" in sys.argv:
6773
return True
6874

69-
# Skip if required migration hasn't been applied yet
70-
try:
71-
recorder = MigrationRecorder(connection)
72-
applied_migrations = recorder.applied_migrations()
73-
if ('netbox_custom_objects', REQUIRED_MIGRATION) not in applied_migrations:
74-
return True
75-
except (DatabaseError, OperationalError, ProgrammingError):
76-
# If we can't check, assume migrations haven't been run
75+
# Below code is to check if the last migration is applied using the migration graph
76+
# However, migrations can can call into get_models() which can call into this function again
77+
# so we have checks to prevent recursion
78+
if _checking_migrations:
7779
return True
7880

79-
return False
81+
# Return cached result if available
82+
if _migrations_checked is not None:
83+
return _migrations_checked
84+
85+
_checking_migrations = True
86+
87+
try:
88+
loader = MigrationLoader(connection)
89+
90+
# Get all migrations for our app from the migration graph
91+
app_migrations = [
92+
key[1] for key in loader.graph.nodes
93+
if key[0] == APP_LABEL
94+
]
95+
96+
if not app_migrations:
97+
result = True
98+
else:
99+
# Get and check if the last migration is applied
100+
last_migration = sorted(app_migrations)[-1]
101+
recorder = MigrationRecorder(connection)
102+
applied_migrations = recorder.applied_migrations()
103+
104+
if (APP_LABEL, last_migration) not in applied_migrations:
105+
result = True
106+
else:
107+
result = False
108+
109+
# Cache the result
110+
_migrations_checked = result
111+
return result
112+
113+
finally:
114+
# Always clear the recursion flag
115+
_checking_migrations = False
80116

81117
def ready(self):
82118
from .models import CustomObjectType

0 commit comments

Comments
 (0)