We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add current NetBox version in the `PluginConfig.validate()` error output
### NetBox version

v4.0.1

### Feature type

New functionality

### Proposed functionality

When [`PluginConfig.validate()`](https://github.com/netbox-community/netbox/blob/4a64a3f6e0d0edf27996422eb2dbe0e197a6bea5/netbox/netbox/plugins/__init__.py#L133) determines that the current NetBox version does not meet the plugin requirements, also print out the current NetBox version in the exception message.

### Use case

Currently the error message only prints the version that the plugin mandates, but due to possible installation directory confusion it would be good to also print the current NetBox version. Example case: https://github.com/netbox-community/netbox/issues/16088


### Database changes

None

### External dependencies

None

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `netbox/netbox/plugins/__init__.py`
Content:
```
1 import collections
2 from importlib import import_module
3 
4 from django.apps import AppConfig
5 from django.core.exceptions import ImproperlyConfigured
6 from django.utils.module_loading import import_string
7 from packaging import version
8 
9 from netbox.registry import registry
10 from netbox.search import register_search
11 from netbox.utils import register_data_backend
12 from .navigation import *
13 from .registration import *
14 from .templates import *
15 from .utils import *
16 
17 # Initialize plugin registry
18 registry['plugins'].update({
19     'graphql_schemas': [],
20     'menus': [],
21     'menu_items': {},
22     'preferences': {},
23     'template_extensions': collections.defaultdict(list),
24 })
25 
26 DEFAULT_RESOURCE_PATHS = {
27     'search_indexes': 'search.indexes',
28     'data_backends': 'data_backends.backends',
29     'graphql_schema': 'graphql.schema',
30     'menu': 'navigation.menu',
31     'menu_items': 'navigation.menu_items',
32     'template_extensions': 'template_content.template_extensions',
33     'user_preferences': 'preferences.preferences',
34 }
35 
36 
37 #
38 # Plugin AppConfig class
39 #
40 
41 class PluginConfig(AppConfig):
42     """
43     Subclass of Django's built-in AppConfig class, to be used for NetBox plugins.
44     """
45     # Plugin metadata
46     author = ''
47     author_email = ''
48     description = ''
49     version = ''
50 
51     # Root URL path under /plugins. If not set, the plugin's label will be used.
52     base_url = None
53 
54     # Minimum/maximum compatible versions of NetBox
55     min_version = None
56     max_version = None
57 
58     # Default configuration parameters
59     default_settings = {}
60 
61     # Mandatory configuration parameters
62     required_settings = []
63 
64     # Middleware classes provided by the plugin
65     middleware = []
66 
67     # Django-rq queues dedicated to the plugin
68     queues = []
69 
70     # Django apps to append to INSTALLED_APPS when plugin requires them.
71     django_apps = []
72 
73     # Optional plugin resources
74     search_indexes = None
75     data_backends = None
76     graphql_schema = None
77     menu = None
78     menu_items = None
79     template_extensions = None
80     user_preferences = None
81 
82     def _load_resource(self, name):
83         # Import from the configured path, if defined.
84         if path := getattr(self, name, None):
85             return import_string(f"{self.__module__}.{path}")
86 
87         # Fall back to the resource's default path. Return None if the module has not been provided.
88         default_path = f'{self.__module__}.{DEFAULT_RESOURCE_PATHS[name]}'
89         default_module, resource_name = default_path.rsplit('.', 1)
90         try:
91             module = import_module(default_module)
92             return getattr(module, resource_name, None)
93         except ModuleNotFoundError:
94             pass
95 
96     def ready(self):
97         from netbox.models.features import register_models
98 
99         # Register models
100         register_models(*self.get_models())
101 
102         plugin_name = self.name.rsplit('.', 1)[-1]
103 
104         # Register search extensions (if defined)
105         search_indexes = self._load_resource('search_indexes') or []
106         for idx in search_indexes:
107             register_search(idx)
108 
109         # Register data backends (if defined)
110         data_backends = self._load_resource('data_backends') or []
111         for backend in data_backends:
112             register_data_backend()(backend)
113 
114         # Register template content (if defined)
115         if template_extensions := self._load_resource('template_extensions'):
116             register_template_extensions(template_extensions)
117 
118         # Register navigation menu and/or menu items (if defined)
119         if menu := self._load_resource('menu'):
120             register_menu(menu)
121         if menu_items := self._load_resource('menu_items'):
122             register_menu_items(self.verbose_name, menu_items)
123 
124         # Register GraphQL schema (if defined)
125         if graphql_schema := self._load_resource('graphql_schema'):
126             register_graphql_schema(graphql_schema)
127 
128         # Register user preferences (if defined)
129         if user_preferences := self._load_resource('user_preferences'):
130             register_user_preferences(plugin_name, user_preferences)
131 
132     @classmethod
133     def validate(cls, user_config, netbox_version):
134 
135         # Enforce version constraints
136         current_version = version.parse(netbox_version)
137         if cls.min_version is not None:
138             min_version = version.parse(cls.min_version)
139             if current_version < min_version:
140                 raise ImproperlyConfigured(
141                     f"Plugin {cls.__module__} requires NetBox minimum version {cls.min_version}."
142                 )
143         if cls.max_version is not None:
144             max_version = version.parse(cls.max_version)
145             if current_version > max_version:
146                 raise ImproperlyConfigured(
147                     f"Plugin {cls.__module__} requires NetBox maximum version {cls.max_version}."
148                 )
149 
150         # Verify required configuration settings
151         for setting in cls.required_settings:
152             if setting not in user_config:
153                 raise ImproperlyConfigured(
154                     f"Plugin {cls.__module__} requires '{setting}' to be present in the PLUGINS_CONFIG section of "
155                     f"configuration.py."
156                 )
157 
158         # Apply default configuration values
159         for setting, value in cls.default_settings.items():
160             if setting not in user_config:
161                 user_config[setting] = value
162
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/netbox/netbox/plugins/__init__.py b/netbox/netbox/plugins/__init__.py
--- a/netbox/netbox/plugins/__init__.py
+++ b/netbox/netbox/plugins/__init__.py
@@ -138,13 +138,15 @@
             min_version = version.parse(cls.min_version)
             if current_version < min_version:
                 raise ImproperlyConfigured(
-                    f"Plugin {cls.__module__} requires NetBox minimum version {cls.min_version}."
+                    f"Plugin {cls.__module__} requires NetBox minimum version {cls.min_version} (current: "
+                    f"{netbox_version})."
                 )
         if cls.max_version is not None:
             max_version = version.parse(cls.max_version)
             if current_version > max_version:
                 raise ImproperlyConfigured(
-                    f"Plugin {cls.__module__} requires NetBox maximum version {cls.max_version}."
+                    f"Plugin {cls.__module__} requires NetBox maximum version {cls.max_version} (current: "
+                    f"{netbox_version})."
                 )
 
         # Verify required configuration settings

{"golden_diff": "diff --git a/netbox/netbox/plugins/__init__.py b/netbox/netbox/plugins/__init__.py\n--- a/netbox/netbox/plugins/__init__.py\n+++ b/netbox/netbox/plugins/__init__.py\n@@ -138,13 +138,15 @@\n             min_version = version.parse(cls.min_version)\n             if current_version < min_version:\n                 raise ImproperlyConfigured(\n-                    f\"Plugin {cls.__module__} requires NetBox minimum version {cls.min_version}.\"\n+                    f\"Plugin {cls.__module__} requires NetBox minimum version {cls.min_version} (current: \"\n+                    f\"{netbox_version}).\"\n                 )\n         if cls.max_version is not None:\n             max_version = version.parse(cls.max_version)\n             if current_version > max_version:\n                 raise ImproperlyConfigured(\n-                    f\"Plugin {cls.__module__} requires NetBox maximum version {cls.max_version}.\"\n+                    f\"Plugin {cls.__module__} requires NetBox maximum version {cls.max_version} (current: \"\n+                    f\"{netbox_version}).\"\n                 )\n \n         # Verify required configuration settings\n", "issue": "Add current NetBox version in the `PluginConfig.validate()` error output\n### NetBox version\n\nv4.0.1\n\n### Feature type\n\nNew functionality\n\n### Proposed functionality\n\nWhen [`PluginConfig.validate()`](https://github.com/netbox-community/netbox/blob/4a64a3f6e0d0edf27996422eb2dbe0e197a6bea5/netbox/netbox/plugins/__init__.py#L133) determines that the current NetBox version does not meet the plugin requirements, also print out the current NetBox version in the exception message.\n\n### Use case\n\nCurrently the error message only prints the version that the plugin mandates, but due to possible installation directory confusion it would be good to also print the current NetBox version. Example case: https://github.com/netbox-community/netbox/issues/16088\r\n\n\n### Database changes\n\nNone\n\n### External dependencies\n\nNone\n", "before_files": [{"content": "import collections\nfrom importlib import import_module\n\nfrom django.apps import AppConfig\nfrom django.core.exceptions import ImproperlyConfigured\nfrom django.utils.module_loading import import_string\nfrom packaging import version\n\nfrom netbox.registry import registry\nfrom netbox.search import register_search\nfrom netbox.utils import register_data_backend\nfrom .navigation import *\nfrom .registration import *\nfrom .templates import *\nfrom .utils import *\n\n# Initialize plugin registry\nregistry['plugins'].update({\n    'graphql_schemas': [],\n    'menus': [],\n    'menu_items': {},\n    'preferences': {},\n    'template_extensions': collections.defaultdict(list),\n})\n\nDEFAULT_RESOURCE_PATHS = {\n    'search_indexes': 'search.indexes',\n    'data_backends': 'data_backends.backends',\n    'graphql_schema': 'graphql.schema',\n    'menu': 'navigation.menu',\n    'menu_items': 'navigation.menu_items',\n    'template_extensions': 'template_content.template_extensions',\n    'user_preferences': 'preferences.preferences',\n}\n\n\n#\n# Plugin AppConfig class\n#\n\nclass PluginConfig(AppConfig):\n    \"\"\"\n    Subclass of Django's built-in AppConfig class, to be used for NetBox plugins.\n    \"\"\"\n    # Plugin metadata\n    author = ''\n    author_email = ''\n    description = ''\n    version = ''\n\n    # Root URL path under /plugins. If not set, the plugin's label will be used.\n    base_url = None\n\n    # Minimum/maximum compatible versions of NetBox\n    min_version = None\n    max_version = None\n\n    # Default configuration parameters\n    default_settings = {}\n\n    # Mandatory configuration parameters\n    required_settings = []\n\n    # Middleware classes provided by the plugin\n    middleware = []\n\n    # Django-rq queues dedicated to the plugin\n    queues = []\n\n    # Django apps to append to INSTALLED_APPS when plugin requires them.\n    django_apps = []\n\n    # Optional plugin resources\n    search_indexes = None\n    data_backends = None\n    graphql_schema = None\n    menu = None\n    menu_items = None\n    template_extensions = None\n    user_preferences = None\n\n    def _load_resource(self, name):\n        # Import from the configured path, if defined.\n        if path := getattr(self, name, None):\n            return import_string(f\"{self.__module__}.{path}\")\n\n        # Fall back to the resource's default path. Return None if the module has not been provided.\n        default_path = f'{self.__module__}.{DEFAULT_RESOURCE_PATHS[name]}'\n        default_module, resource_name = default_path.rsplit('.', 1)\n        try:\n            module = import_module(default_module)\n            return getattr(module, resource_name, None)\n        except ModuleNotFoundError:\n            pass\n\n    def ready(self):\n        from netbox.models.features import register_models\n\n        # Register models\n        register_models(*self.get_models())\n\n        plugin_name = self.name.rsplit('.', 1)[-1]\n\n        # Register search extensions (if defined)\n        search_indexes = self._load_resource('search_indexes') or []\n        for idx in search_indexes:\n            register_search(idx)\n\n        # Register data backends (if defined)\n        data_backends = self._load_resource('data_backends') or []\n        for backend in data_backends:\n            register_data_backend()(backend)\n\n        # Register template content (if defined)\n        if template_extensions := self._load_resource('template_extensions'):\n            register_template_extensions(template_extensions)\n\n        # Register navigation menu and/or menu items (if defined)\n        if menu := self._load_resource('menu'):\n            register_menu(menu)\n        if menu_items := self._load_resource('menu_items'):\n            register_menu_items(self.verbose_name, menu_items)\n\n        # Register GraphQL schema (if defined)\n        if graphql_schema := self._load_resource('graphql_schema'):\n            register_graphql_schema(graphql_schema)\n\n        # Register user preferences (if defined)\n        if user_preferences := self._load_resource('user_preferences'):\n            register_user_preferences(plugin_name, user_preferences)\n\n    @classmethod\n    def validate(cls, user_config, netbox_version):\n\n        # Enforce version constraints\n        current_version = version.parse(netbox_version)\n        if cls.min_version is not None:\n            min_version = version.parse(cls.min_version)\n            if current_version < min_version:\n                raise ImproperlyConfigured(\n                    f\"Plugin {cls.__module__} requires NetBox minimum version {cls.min_version}.\"\n                )\n        if cls.max_version is not None:\n            max_version = version.parse(cls.max_version)\n            if current_version > max_version:\n                raise ImproperlyConfigured(\n                    f\"Plugin {cls.__module__} requires NetBox maximum version {cls.max_version}.\"\n                )\n\n        # Verify required configuration settings\n        for setting in cls.required_settings:\n            if setting not in user_config:\n                raise ImproperlyConfigured(\n                    f\"Plugin {cls.__module__} requires '{setting}' to be present in the PLUGINS_CONFIG section of \"\n                    f\"configuration.py.\"\n                )\n\n        # Apply default configuration values\n        for setting, value in cls.default_settings.items():\n            if setting not in user_config:\n                user_config[setting] = value\n", "path": "netbox/netbox/plugins/__init__.py"}], "after_files": [{"content": "import collections\nfrom importlib import import_module\n\nfrom django.apps import AppConfig\nfrom django.core.exceptions import ImproperlyConfigured\nfrom django.utils.module_loading import import_string\nfrom packaging import version\n\nfrom netbox.registry import registry\nfrom netbox.search import register_search\nfrom netbox.utils import register_data_backend\nfrom .navigation import *\nfrom .registration import *\nfrom .templates import *\nfrom .utils import *\n\n# Initialize plugin registry\nregistry['plugins'].update({\n    'graphql_schemas': [],\n    'menus': [],\n    'menu_items': {},\n    'preferences': {},\n    'template_extensions': collections.defaultdict(list),\n})\n\nDEFAULT_RESOURCE_PATHS = {\n    'search_indexes': 'search.indexes',\n    'data_backends': 'data_backends.backends',\n    'graphql_schema': 'graphql.schema',\n    'menu': 'navigation.menu',\n    'menu_items': 'navigation.menu_items',\n    'template_extensions': 'template_content.template_extensions',\n    'user_preferences': 'preferences.preferences',\n}\n\n\n#\n# Plugin AppConfig class\n#\n\nclass PluginConfig(AppConfig):\n    \"\"\"\n    Subclass of Django's built-in AppConfig class, to be used for NetBox plugins.\n    \"\"\"\n    # Plugin metadata\n    author = ''\n    author_email = ''\n    description = ''\n    version = ''\n\n    # Root URL path under /plugins. If not set, the plugin's label will be used.\n    base_url = None\n\n    # Minimum/maximum compatible versions of NetBox\n    min_version = None\n    max_version = None\n\n    # Default configuration parameters\n    default_settings = {}\n\n    # Mandatory configuration parameters\n    required_settings = []\n\n    # Middleware classes provided by the plugin\n    middleware = []\n\n    # Django-rq queues dedicated to the plugin\n    queues = []\n\n    # Django apps to append to INSTALLED_APPS when plugin requires them.\n    django_apps = []\n\n    # Optional plugin resources\n    search_indexes = None\n    data_backends = None\n    graphql_schema = None\n    menu = None\n    menu_items = None\n    template_extensions = None\n    user_preferences = None\n\n    def _load_resource(self, name):\n        # Import from the configured path, if defined.\n        if path := getattr(self, name, None):\n            return import_string(f\"{self.__module__}.{path}\")\n\n        # Fall back to the resource's default path. Return None if the module has not been provided.\n        default_path = f'{self.__module__}.{DEFAULT_RESOURCE_PATHS[name]}'\n        default_module, resource_name = default_path.rsplit('.', 1)\n        try:\n            module = import_module(default_module)\n            return getattr(module, resource_name, None)\n        except ModuleNotFoundError:\n            pass\n\n    def ready(self):\n        from netbox.models.features import register_models\n\n        # Register models\n        register_models(*self.get_models())\n\n        plugin_name = self.name.rsplit('.', 1)[-1]\n\n        # Register search extensions (if defined)\n        search_indexes = self._load_resource('search_indexes') or []\n        for idx in search_indexes:\n            register_search(idx)\n\n        # Register data backends (if defined)\n        data_backends = self._load_resource('data_backends') or []\n        for backend in data_backends:\n            register_data_backend()(backend)\n\n        # Register template content (if defined)\n        if template_extensions := self._load_resource('template_extensions'):\n            register_template_extensions(template_extensions)\n\n        # Register navigation menu and/or menu items (if defined)\n        if menu := self._load_resource('menu'):\n            register_menu(menu)\n        if menu_items := self._load_resource('menu_items'):\n            register_menu_items(self.verbose_name, menu_items)\n\n        # Register GraphQL schema (if defined)\n        if graphql_schema := self._load_resource('graphql_schema'):\n            register_graphql_schema(graphql_schema)\n\n        # Register user preferences (if defined)\n        if user_preferences := self._load_resource('user_preferences'):\n            register_user_preferences(plugin_name, user_preferences)\n\n    @classmethod\n    def validate(cls, user_config, netbox_version):\n\n        # Enforce version constraints\n        current_version = version.parse(netbox_version)\n        if cls.min_version is not None:\n            min_version = version.parse(cls.min_version)\n            if current_version < min_version:\n                raise ImproperlyConfigured(\n                    f\"Plugin {cls.__module__} requires NetBox minimum version {cls.min_version} (current: \"\n                    f\"{netbox_version}).\"\n                )\n        if cls.max_version is not None:\n            max_version = version.parse(cls.max_version)\n            if current_version > max_version:\n                raise ImproperlyConfigured(\n                    f\"Plugin {cls.__module__} requires NetBox maximum version {cls.max_version} (current: \"\n                    f\"{netbox_version}).\"\n                )\n\n        # Verify required configuration settings\n        for setting in cls.required_settings:\n            if setting not in user_config:\n                raise ImproperlyConfigured(\n                    f\"Plugin {cls.__module__} requires '{setting}' to be present in the PLUGINS_CONFIG section of \"\n                    f\"configuration.py.\"\n                )\n\n        # Apply default configuration values\n        for setting, value in cls.default_settings.items():\n            if setting not in user_config:\n                user_config[setting] = value\n", "path": "netbox/netbox/plugins/__init__.py"}]}