Răsfoiți Sursa

review feedback

Arthur 1 zi în urmă
părinte
comite
7fff472436

+ 9 - 5
netbox/netbox/plugins/__init__.py

@@ -135,12 +135,16 @@ class PluginConfig(AppConfig):
         if user_preferences := self._load_resource('user_preferences'):
             register_user_preferences(plugin_name, user_preferences)
 
-        # Register serializer resolver (if explicitly defined). No default path is attempted.
+        # Register serializer resolver (if defined)
         if self.serializer_resolver:
-            register_serializer_resolver(
-                self.label,
-                import_string(f"{self.__module__}.{self.serializer_resolver}"),
-            )
+            resolver_path = f"{self.__module__}.{self.serializer_resolver}"
+            try:
+                resolver = import_string(resolver_path)
+            except ImportError as e:
+                raise ImproperlyConfigured(
+                    f"Invalid serializer resolver path for plugin {self.__module__}: {resolver_path}"
+                ) from e
+            register_serializer_resolver(self.label, resolver)
 
     @classmethod
     def validate(cls, user_config, netbox_version):

+ 4 - 0
netbox/netbox/plugins/registration.py

@@ -103,4 +103,8 @@ def register_serializer_resolver(app_label, resolver):
     """
     if not callable(resolver):
         raise TypeError(_("Serializer resolver must be callable"))
+    if app_label in registry['serializer_resolvers']:
+        raise ValueError(
+            _("A serializer resolver is already registered for app '{app_label}'").format(app_label=app_label)
+        )
     registry['serializer_resolvers'][app_label] = resolver

+ 5 - 0
netbox/utilities/tests/test_api.py

@@ -549,6 +549,11 @@ class SerializerResolverRegistryTestCase(TestCase):
         with self.assertRaises(TypeError):
             register_serializer_resolver('dcim', 'not a callable')
 
+    def test_register_rejects_duplicate_app_registration(self):
+        register_serializer_resolver('dcim', lambda model, prefix='': _ResolvedSerializerA)
+        with self.assertRaises(ValueError):
+            register_serializer_resolver('dcim', lambda model, prefix='': _ResolvedSerializerB)
+
     def test_raising_resolver_falls_through_to_default(self):
         def broken_resolver(model, prefix=''):
             raise RuntimeError("intentional failure")