From 3c2af9782379e19f6a70f55fc0b076348bb5f9eb Mon Sep 17 00:00:00 2001 From: Arthur Hanson Date: Tue, 27 Aug 2024 10:02:03 -0700 Subject: [PATCH] 17219 use custom json encoder --- netbox/core/views.py | 25 ++++------------------ netbox/templates/core/inc/config_data.html | 2 +- netbox/utilities/json.py | 13 +++++++++++ 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/netbox/core/views.py b/netbox/core/views.py index 26e04a8d8..bc45089f1 100644 --- a/netbox/core/views.py +++ b/netbox/core/views.py @@ -32,6 +32,7 @@ from netbox.views.generic.base import BaseObjectView from netbox.views.generic.mixins import TableMixin from utilities.forms import ConfirmationForm from utilities.htmx import htmx_partial +from utilities.json import ConfigJSONEncoder from utilities.query import count_related from utilities.views import ContentTypePermissionRequiredMixin, GetRelatedModelsMixin, register_model_view from . import filtersets, forms, tables @@ -523,23 +524,6 @@ class SystemView(UserPassesTestMixin, View): def test_func(self): return self.request.user.is_staff - def map_validators(self, validator): - if isinstance(validator, dict): - for k, v in validator.items(): - if isinstance(v, tuple): - validator[k] = type(v[0]).__name__ - else: - validator[k] = self.map_validators(v) - - elif isinstance(validator, list): - for index, v in enumerate(validator): - validator[index] = self.map_validators(v) - - elif issubclass(type(validator), CustomValidator): - return type(validator).__name__ - - return validator - def get(self, request): # System stats @@ -578,10 +562,6 @@ class SystemView(UserPassesTestMixin, View): # Fall back to using the active config data if no record is found config = get_config() - # If Custom Validators is function (in configuration.py) get function name - if hasattr(config, 'CUSTOM_VALIDATORS') and config.CUSTOM_VALIDATORS: - config.CUSTOM_VALIDATORS = self.map_validators(config.CUSTOM_VALIDATORS) - # Raw data export if 'export' in request.GET: params = [param.name for param in PARAMS] @@ -601,6 +581,9 @@ class SystemView(UserPassesTestMixin, View): plugins_table = tables.PluginTable(plugins, orderable=False) plugins_table.configure(request) + if hasattr(config, 'CUSTOM_VALIDATORS') and config.CUSTOM_VALIDATORS: + config.CUSTOM_VALIDATORS = json.dumps(config.CUSTOM_VALIDATORS, cls=ConfigJSONEncoder, indent=4) + return render(request, 'core/system.html', { 'stats': stats, 'plugins_table': plugins_table, diff --git a/netbox/templates/core/inc/config_data.html b/netbox/templates/core/inc/config_data.html index 8305b5540..41471a103 100644 --- a/netbox/templates/core/inc/config_data.html +++ b/netbox/templates/core/inc/config_data.html @@ -95,7 +95,7 @@ {% trans "Custom validators" %} {% if config.CUSTOM_VALIDATORS %} -
{{ config.CUSTOM_VALIDATORS|json }}
+
{{ config.CUSTOM_VALIDATORS }}
{% else %} {{ ''|placeholder }} {% endif %} diff --git a/netbox/utilities/json.py b/netbox/utilities/json.py index 5574ff36f..926df898e 100644 --- a/netbox/utilities/json.py +++ b/netbox/utilities/json.py @@ -3,6 +3,7 @@ import decimal from django.core.serializers.json import DjangoJSONEncoder __all__ = ( + 'ConfigJSONEncoder', 'CustomFieldJSONEncoder', ) @@ -15,3 +16,15 @@ class CustomFieldJSONEncoder(DjangoJSONEncoder): if isinstance(o, decimal.Decimal): return float(o) return super().default(o) + + +class ConfigJSONEncoder(DjangoJSONEncoder): + """ + Override Django's built-in JSON encoder to save python functions as function names. + """ + def default(self, o): + from extras.validators import CustomValidator + + if issubclass(type(o), CustomValidator): + return type(o).__name__ + return super().default(o)