Преглед изворни кода

Fixes #20290: Avoid exceptions when upgrading to v4.4 from early releases due to missing ObjectTypes table

Jeremy Stretch пре 4 месеци
родитељ
комит
5ceb6a60da
2 измењених фајлова са 17 додато и 4 уклоњено
  1. 9 1
      netbox/core/models/object_types.py
  2. 8 3
      netbox/netbox/models/features.py

+ 9 - 1
netbox/core/models/object_types.py

@@ -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)

+ 8 - 3
netbox/netbox/models/features.py

@@ -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)