From d23b9370f6c8905c5425237e0329a949f4c2af5f Mon Sep 17 00:00:00 2001 From: Arthur Hanson Date: Tue, 27 Aug 2024 11:19:16 -0700 Subject: [PATCH] 17219 fix custom validator display if function (#17247) * 17219 fix custom validator display if function * 17219 fix custom validator display if function * 17219 use custom json encoder * Fix system config export --------- Co-authored-by: Jeremy Stretch --- netbox/core/views.py | 8 +++++++- netbox/templates/core/inc/config_data.html | 2 +- netbox/utilities/json.py | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/netbox/core/views.py b/netbox/core/views.py index d453cf004..230134cc3 100644 --- a/netbox/core/views.py +++ b/netbox/core/views.py @@ -25,12 +25,14 @@ from rq.registry import ( from rq.worker import Worker from rq.worker_registration import clean_worker_registry +from extras.validators import CustomValidator from netbox.config import get_config, PARAMS from netbox.views import generic 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 @@ -572,13 +574,17 @@ class SystemView(UserPassesTestMixin, View): k: getattr(config, k) for k in sorted(params) }, } - response = HttpResponse(json.dumps(data, indent=4), content_type='text/json') + response = HttpResponse(json.dumps(data, cls=ConfigJSONEncoder, indent=4), content_type='text/json') response['Content-Disposition'] = 'attachment; filename="netbox.json"' return response plugins_table = tables.PluginTable(plugins, orderable=False) plugins_table.configure(request) + # Serialize any CustomValidator classes + 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..3114be1bf 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,16 @@ 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 serialize CustomValidator classes as strings. + """ + def default(self, o): + from extras.validators import CustomValidator + + if issubclass(type(o), CustomValidator): + return type(o).__name__ + + return super().default(o)