diff --git a/netbox/core/views.py b/netbox/core/views.py
index 9d9d6e2be..b18937308 100644
--- a/netbox/core/views.py
+++ b/netbox/core/views.py
@@ -27,6 +27,7 @@ from netbox.plugins.utils import get_installed_plugins
from netbox.views import generic
from netbox.views.generic.base import BaseObjectView
from netbox.views.generic.mixins import TableMixin
+from utilities.apps import get_installed_apps
from utilities.data import shallow_compare_dict
from utilities.forms import ConfirmationForm
from utilities.htmx import htmx_partial
@@ -575,6 +576,9 @@ class SystemView(UserPassesTestMixin, View):
'rq_worker_count': Worker.count(get_connection('default')),
}
+ # Django apps
+ django_apps = get_installed_apps()
+
# Configuration
config = get_config()
@@ -593,6 +597,7 @@ class SystemView(UserPassesTestMixin, View):
params = [param.name for param in PARAMS]
data = {
**stats,
+ 'django_apps': django_apps,
'plugins': plugins,
'config': {
k: getattr(config, k) for k in sorted(params)
@@ -612,6 +617,7 @@ class SystemView(UserPassesTestMixin, View):
return render(request, 'core/system.html', {
'stats': stats,
+ 'django_apps': django_apps,
'config': config,
'plugins': plugins,
'objects': objects,
diff --git a/netbox/netbox/api/views.py b/netbox/netbox/api/views.py
index 82124e1c5..6740700b8 100644
--- a/netbox/netbox/api/views.py
+++ b/netbox/netbox/api/views.py
@@ -1,7 +1,6 @@
import platform
from django import __version__ as DJANGO_VERSION
-from django.apps import apps
from django.conf import settings
from django_rq.queues import get_connection
from drf_spectacular.types import OpenApiTypes
@@ -13,6 +12,7 @@ from rq.worker import Worker
from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired
from netbox.plugins.utils import get_installed_plugins
+from utilities.apps import get_installed_apps
class APIRootView(APIView):
@@ -52,21 +52,10 @@ class StatusView(APIView):
@extend_schema(responses={200: OpenApiTypes.OBJECT})
def get(self, request):
- # Gather the version numbers from all installed Django apps
- installed_apps = {}
- for app_config in apps.get_app_configs():
- app = app_config.module
- version = getattr(app, 'VERSION', getattr(app, '__version__', None))
- if version:
- if type(version) is tuple:
- version = '.'.join(str(n) for n in version)
- installed_apps[app_config.name] = version
- installed_apps = {k: v for k, v in sorted(installed_apps.items())}
-
return Response({
'django-version': DJANGO_VERSION,
'hostname': settings.HOSTNAME,
- 'installed-apps': installed_apps,
+ 'installed_apps': get_installed_apps(),
'netbox-version': settings.RELEASE.version,
'netbox-full-version': settings.RELEASE.full_version,
'plugins': get_installed_plugins(),
diff --git a/netbox/templates/core/system.html b/netbox/templates/core/system.html
index 1e2914b3c..092bc708d 100644
--- a/netbox/templates/core/system.html
+++ b/netbox/templates/core/system.html
@@ -45,6 +45,10 @@
+
+ {% trans "System hostname" %} |
+ {{ settings.HOSTNAME }} |
+
{% trans "NetBox release" %} |
@@ -93,6 +97,23 @@
|
+
+
+ {% if django_apps %}
+
+ {% for app_name, version in django_apps.items %}
+
+ {{ app_name }} |
+ {{ version }} |
+
+ {% endfor %}
+
+ {% else %}
+
+ {% trans "None found" %}
+
+ {% endif %}
+
@@ -115,14 +136,20 @@
-
- {% for plugin, version in plugins.items %}
-
- {{ plugin }} |
- {{ version }} |
-
- {% endfor %}
-
+ {% if plugins %}
+
+ {% for plugin, version in plugins.items %}
+
+ {{ plugin }} |
+ {{ version }} |
+
+ {% endfor %}
+
+ {% else %}
+
+ {% trans "No plugins are installed." %}
+
+ {% endif %}
diff --git a/netbox/utilities/apps.py b/netbox/utilities/apps.py
new file mode 100644
index 000000000..b5445c8c4
--- /dev/null
+++ b/netbox/utilities/apps.py
@@ -0,0 +1,17 @@
+from django.apps import apps
+
+
+def get_installed_apps():
+ """
+ Return the name and version number for each installed Django app.
+ """
+ installed_apps = {}
+ for app_config in apps.get_app_configs():
+ app = app_config.module
+ if version := getattr(app, 'VERSION', getattr(app, '__version__', None)):
+ if type(version) is tuple:
+ version = '.'.join(str(n) for n in version)
+ installed_apps[app_config.name] = version
+ return {
+ k: v for k, v in sorted(installed_apps.items())
+ }