mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-25 18:08:38 -06:00
Closes #10699: Remove custom import_object() function
This commit is contained in:
parent
a44eed5001
commit
85a4b1f881
@ -40,6 +40,7 @@ A new `PluginMenu` class has been introduced, which enables a plugin to inject a
|
|||||||
* [#9045](https://github.com/netbox-community/netbox/issues/9045) - Remove legacy ASN field from provider model
|
* [#9045](https://github.com/netbox-community/netbox/issues/9045) - Remove legacy ASN field from provider model
|
||||||
* [#9046](https://github.com/netbox-community/netbox/issues/9046) - Remove legacy contact fields from provider model
|
* [#9046](https://github.com/netbox-community/netbox/issues/9046) - Remove legacy contact fields from provider model
|
||||||
* [#10358](https://github.com/netbox-community/netbox/issues/10358) - Raise minimum required PostgreSQL version from 10 to 11
|
* [#10358](https://github.com/netbox-community/netbox/issues/10358) - Raise minimum required PostgreSQL version from 10 to 11
|
||||||
|
* [#10699](https://github.com/netbox-community/netbox/issues/10699) - Remove custom `import_object()` function
|
||||||
|
|
||||||
### REST API Changes
|
### REST API Changes
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ from packaging import version
|
|||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.template.loader import get_template
|
from django.template.loader import get_template
|
||||||
|
from django.utils.module_loading import import_string
|
||||||
|
|
||||||
from extras.plugins.utils import import_object
|
|
||||||
from extras.registry import registry
|
from extras.registry import registry
|
||||||
from netbox.navigation import MenuGroup
|
from netbox.navigation import MenuGroup
|
||||||
from netbox.search import register_search
|
from netbox.search import register_search
|
||||||
@ -71,31 +71,46 @@ class PluginConfig(AppConfig):
|
|||||||
def ready(self):
|
def ready(self):
|
||||||
plugin_name = self.name.rsplit('.', 1)[-1]
|
plugin_name = self.name.rsplit('.', 1)[-1]
|
||||||
|
|
||||||
# Search extensions
|
# Register search extensions (if defined)
|
||||||
search_indexes = import_object(f"{self.__module__}.{self.search_indexes}") or []
|
try:
|
||||||
for idx in search_indexes:
|
search_indexes = import_string(f"{self.__module__}.{self.search_indexes}")
|
||||||
register_search()(idx)
|
for idx in search_indexes:
|
||||||
|
register_search()(idx)
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Register template content (if defined)
|
# Register template content (if defined)
|
||||||
template_extensions = import_object(f"{self.__module__}.{self.template_extensions}")
|
try:
|
||||||
if template_extensions is not None:
|
template_extensions = import_string(f"{self.__module__}.{self.template_extensions}")
|
||||||
register_template_extensions(template_extensions)
|
register_template_extensions(template_extensions)
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Register navigation menu or menu items (if defined)
|
# Register navigation menu and/or menu items (if defined)
|
||||||
if menu := import_object(f"{self.__module__}.{self.menu}"):
|
try:
|
||||||
|
menu = import_string(f"{self.__module__}.{self.menu}")
|
||||||
register_menu(menu)
|
register_menu(menu)
|
||||||
if menu_items := import_object(f"{self.__module__}.{self.menu_items}"):
|
except ImportError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
menu_items = import_string(f"{self.__module__}.{self.menu_items}")
|
||||||
register_menu_items(self.verbose_name, menu_items)
|
register_menu_items(self.verbose_name, menu_items)
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Register GraphQL schema (if defined)
|
# Register GraphQL schema (if defined)
|
||||||
graphql_schema = import_object(f"{self.__module__}.{self.graphql_schema}")
|
try:
|
||||||
if graphql_schema is not None:
|
graphql_schema = import_string(f"{self.__module__}.{self.graphql_schema}")
|
||||||
register_graphql_schema(graphql_schema)
|
register_graphql_schema(graphql_schema)
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Register user preferences (if defined)
|
# Register user preferences (if defined)
|
||||||
user_preferences = import_object(f"{self.__module__}.{self.user_preferences}")
|
try:
|
||||||
if user_preferences is not None:
|
user_preferences = import_string(f"{self.__module__}.{self.user_preferences}")
|
||||||
register_user_preferences(plugin_name, user_preferences)
|
register_user_preferences(plugin_name, user_preferences)
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate(cls, user_config, netbox_version):
|
def validate(cls, user_config, netbox_version):
|
||||||
|
@ -3,8 +3,7 @@ from django.conf import settings
|
|||||||
from django.conf.urls import include
|
from django.conf.urls import include
|
||||||
from django.contrib.admin.views.decorators import staff_member_required
|
from django.contrib.admin.views.decorators import staff_member_required
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
from django.utils.module_loading import import_string
|
||||||
from extras.plugins.utils import import_object
|
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
@ -25,15 +24,19 @@ for plugin_path in settings.PLUGINS:
|
|||||||
base_url = getattr(app, 'base_url') or app.label
|
base_url = getattr(app, 'base_url') or app.label
|
||||||
|
|
||||||
# Check if the plugin specifies any base URLs
|
# Check if the plugin specifies any base URLs
|
||||||
urlpatterns = import_object(f"{plugin_path}.urls.urlpatterns")
|
try:
|
||||||
if urlpatterns is not None:
|
urlpatterns = import_string(f"{plugin_path}.urls.urlpatterns")
|
||||||
plugin_patterns.append(
|
plugin_patterns.append(
|
||||||
path(f"{base_url}/", include((urlpatterns, app.label)))
|
path(f"{base_url}/", include((urlpatterns, app.label)))
|
||||||
)
|
)
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Check if the plugin specifies any API URLs
|
# Check if the plugin specifies any API URLs
|
||||||
urlpatterns = import_object(f"{plugin_path}.api.urls.urlpatterns")
|
try:
|
||||||
if urlpatterns is not None:
|
urlpatterns = import_string(f"{plugin_path}.api.urls.urlpatterns")
|
||||||
plugin_api_patterns.append(
|
plugin_api_patterns.append(
|
||||||
path(f"{base_url}/", include((urlpatterns, f"{app.label}-api")))
|
path(f"{base_url}/", include((urlpatterns, f"{app.label}-api")))
|
||||||
)
|
)
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
import importlib.util
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def import_object(module_and_object):
|
|
||||||
"""
|
|
||||||
Import a specific object from a specific module by name, such as "extras.plugins.utils.import_object".
|
|
||||||
|
|
||||||
Returns the imported object, or None if it doesn't exist.
|
|
||||||
"""
|
|
||||||
target_module_name, object_name = module_and_object.rsplit('.', 1)
|
|
||||||
module_hierarchy = target_module_name.split('.')
|
|
||||||
|
|
||||||
# Iterate through the module hierarchy, checking for the existence of each successive submodule.
|
|
||||||
# We have to do this rather than jumping directly to calling find_spec(target_module_name)
|
|
||||||
# because find_spec will raise a ModuleNotFoundError if any parent module of target_module_name does not exist.
|
|
||||||
module_name = ""
|
|
||||||
for module_component in module_hierarchy:
|
|
||||||
module_name = f"{module_name}.{module_component}" if module_name else module_component
|
|
||||||
spec = importlib.util.find_spec(module_name)
|
|
||||||
if spec is None:
|
|
||||||
# No such module
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Okay, target_module_name exists. Load it if not already loaded
|
|
||||||
if target_module_name in sys.modules:
|
|
||||||
module = sys.modules[target_module_name]
|
|
||||||
else:
|
|
||||||
module = importlib.util.module_from_spec(spec)
|
|
||||||
sys.modules[target_module_name] = module
|
|
||||||
spec.loader.exec_module(module)
|
|
||||||
|
|
||||||
return getattr(module, object_name, None)
|
|
Loading…
Reference in New Issue
Block a user