diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py index 1bd6e89d8..26bd7de65 100644 --- a/netbox/netbox/views/generic/object_views.py +++ b/netbox/netbox/views/generic/object_views.py @@ -18,8 +18,7 @@ from utilities.error_handlers import handle_protectederror from utilities.exceptions import AbortRequest, PermissionsViolation from utilities.forms import ConfirmationForm, restrict_form_fields from utilities.permissions import get_permission_for_model -from utilities.querydict import normalize_querydict -from utilities.utils import prepare_cloned_fields +from utilities.querydict import normalize_querydict, prepare_cloned_fields from utilities.views import GetReturnURLMixin, get_viewname from .base import BaseObjectView from .mixins import ActionsMixin, TableMixin diff --git a/netbox/utilities/querydict.py b/netbox/utilities/querydict.py index 190b296d6..a2296cb1a 100644 --- a/netbox/utilities/querydict.py +++ b/netbox/utilities/querydict.py @@ -1,9 +1,12 @@ +from urllib.parse import urlencode + from django.http import QueryDict from django.utils.datastructures import MultiValueDict __all__ = ( 'dict_to_querydict', 'normalize_querydict', + 'prepare_cloned_fields', ) @@ -36,3 +39,26 @@ def normalize_querydict(querydict): return { k: v if len(v) > 1 else v[0] for k, v in querydict.lists() } + + +def prepare_cloned_fields(instance): + """ + Generate a QueryDict comprising attributes from an object's clone() method. + """ + # Generate the clone attributes from the instance + if not hasattr(instance, 'clone'): + return QueryDict(mutable=True) + attrs = instance.clone() + + # Prepare QueryDict parameters + params = [] + for key, value in attrs.items(): + if type(value) in (list, tuple): + params.extend([(key, v) for v in value]) + elif value not in (False, None): + params.append((key, value)) + else: + params.append((key, '')) + + # Return a QueryDict with the parameters + return QueryDict(urlencode(params), mutable=True) diff --git a/netbox/utilities/templatetags/buttons.py b/netbox/utilities/templatetags/buttons.py index 1f863bca8..c4a1086f0 100644 --- a/netbox/utilities/templatetags/buttons.py +++ b/netbox/utilities/templatetags/buttons.py @@ -4,7 +4,7 @@ from django.urls import NoReverseMatch, reverse from core.models import ObjectType from extras.models import Bookmark, ExportTemplate -from utilities.utils import prepare_cloned_fields +from utilities.querydict import prepare_cloned_fields from utilities.views import get_viewname __all__ = ( diff --git a/netbox/utilities/utils.py b/netbox/utilities/utils.py index 62195e4c7..7a22881f6 100644 --- a/netbox/utilities/utils.py +++ b/netbox/utilities/utils.py @@ -1,8 +1,5 @@ -from urllib.parse import urlencode - from django.db.models import Count, ManyToOneRel, OuterRef, Subquery from django.db.models.functions import Coalesce -from django.http import QueryDict from django.utils import timezone from django.utils.timezone import localtime @@ -69,29 +66,6 @@ def dict_to_filter_params(d, prefix=''): return params -def prepare_cloned_fields(instance): - """ - Generate a QueryDict comprising attributes from an object's clone() method. - """ - # Generate the clone attributes from the instance - if not hasattr(instance, 'clone'): - return QueryDict(mutable=True) - attrs = instance.clone() - - # Prepare querydict parameters - params = [] - for key, value in attrs.items(): - if type(value) in (list, tuple): - params.extend([(key, v) for v in value]) - elif value not in (False, None): - params.append((key, value)) - else: - params.append((key, '')) - - # Return a QueryDict with the parameters - return QueryDict(urlencode(params), mutable=True) - - def content_type_name(ct, include_app=True): """ Return a human-friendly ContentType name (e.g. "DCIM > Site").