diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index 59ffbb652..c6b87d1e4 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -22,6 +22,7 @@ * [#8088](https://github.com/netbox-community/netbox/issues/8088) - Improve legibility of text in labels with light-colored backgrounds * [#8092](https://github.com/netbox-community/netbox/issues/8092) - Rack elevations should not include device asset tags * [#8096](https://github.com/netbox-community/netbox/issues/8096) - Fix DataError during change logging of objects with very long string representations +* [#8101](https://github.com/netbox-community/netbox/issues/8101) - Preserve return URL when using "create and add another" button * [#8102](https://github.com/netbox-community/netbox/issues/8102) - Raise validation error when attempting to assign an IP address to multiple objects --- diff --git a/netbox/netbox/views/generic.py b/netbox/netbox/views/generic.py index 7b0d3e472..feff2ca39 100644 --- a/netbox/netbox/views/generic.py +++ b/netbox/netbox/views/generic.py @@ -371,8 +371,11 @@ class ObjectEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View): redirect_url = request.path # If the object has clone_fields, pre-populate a new instance of the form - if hasattr(obj, 'clone_fields'): - redirect_url += f"?{prepare_cloned_fields(obj)}" + params = prepare_cloned_fields(obj) + if 'return_url' in request.GET: + params['return_url'] = request.GET.get('return_url') + if params: + redirect_url += f"?{params.urlencode()}" return redirect(redirect_url) diff --git a/netbox/utilities/templatetags/buttons.py b/netbox/utilities/templatetags/buttons.py index 3608f5a7c..ecbcb1143 100644 --- a/netbox/utilities/templatetags/buttons.py +++ b/netbox/utilities/templatetags/buttons.py @@ -30,7 +30,7 @@ def clone_button(instance): url = reverse(_get_viewname(instance, 'add')) # Populate cloned field values - param_string = prepare_cloned_fields(instance) + param_string = prepare_cloned_fields(instance).urlencode() if param_string: url = f'{url}?{param_string}' diff --git a/netbox/utilities/utils.py b/netbox/utilities/utils.py index f12bc2569..3234135fb 100644 --- a/netbox/utilities/utils.py +++ b/netbox/utilities/utils.py @@ -8,6 +8,7 @@ from typing import Any, Dict, List, Tuple from django.core.serializers import serialize from django.db.models import Count, OuterRef, Subquery from django.db.models.functions import Coalesce +from django.http import QueryDict from jinja2.sandbox import SandboxedEnvironment from mptt.models import MPTTModel @@ -249,10 +250,8 @@ def prepare_cloned_fields(instance): for tag in instance.tags.all(): params.append(('tags', tag.pk)) - # Concatenate parameters into a URL query string - param_string = '&'.join([f'{k}={v}' for k, v in params]) - - return param_string + # Return a QueryDict with the parameters + return QueryDict('&'.join([f'{k}={v}' for k, v in params]), mutable=True) def shallow_compare_dict(source_dict, destination_dict, exclude=None):