Fixes #20290: Avoid exceptions when upgrading to v4.4 from early releases due to missing ObjectTypes table
Some checks are pending
CI / build (20.x, 3.10) (push) Waiting to run
CI / build (20.x, 3.11) (push) Waiting to run
CI / build (20.x, 3.12) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, actions) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, python) (push) Waiting to run

This commit is contained in:
Jeremy Stretch 2025-10-06 14:11:45 -04:00
parent 33d4759871
commit 5ceb6a60da
2 changed files with 17 additions and 4 deletions

View File

@ -5,7 +5,7 @@ from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.indexes import GinIndex
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.db import connection, models
from django.db.models import Q
from django.utils.translation import gettext as _
@ -66,6 +66,14 @@ class ObjectTypeManager(models.Manager):
"""
from netbox.models.features import get_model_features, model_is_public
# TODO: Remove this in NetBox v5.0
# If the ObjectType table has not yet been provisioned (e.g. because we're in a pre-v4.4 migration),
# fall back to ContentType.
if 'core_objecttype' not in connection.introspection.table_names():
ct = ContentType.objects.get_for_model(model, for_concrete_model=for_concrete_model)
ct.features = get_model_features(ct.model_class())
return ct
if not inspect.isclass(model):
model = model.__class__
opts = self._get_opts(model, for_concrete_model)

View File

@ -673,10 +673,15 @@ def has_feature(model_or_ct, feature):
# If an ObjectType was passed, we can use it directly
if type(model_or_ct) is ObjectType:
ot = model_or_ct
# If a ContentType was passed, resolve its model class
# If a ContentType was passed, resolve its model class and run the associated feature test
elif type(model_or_ct) is ContentType:
model_class = model_or_ct.model_class()
ot = ObjectType.objects.get_for_model(model_class) if model_class else None
model = model_or_ct.model_class()
try:
test_func = registry['model_features'][feature]
except KeyError:
# Unknown feature
return False
return test_func(model)
# For anything else, look up the ObjectType
else:
ot = ObjectType.objects.get_for_model(model_or_ct)