Просмотр исходного кода

Closes #648: Pre-populate forms when selecting "create and add another"

Jeremy Stretch 6 лет назад
Родитель
Сommit
2956eff051

+ 1 - 0
docs/release-notes/version-2.7.md

@@ -128,6 +128,7 @@ PATCH) to maintain backward compatibility. This behavior will be discontinued be
 ## Enhancements
 
 * [#33](https://github.com/digitalocean/netbox/issues/33) - Add ability to clone objects (pre-populate form fields)
+* [#648](https://github.com/digitalocean/netbox/issues/648) - Pre-populate forms when selecting "create and add another"
 * [#792](https://github.com/digitalocean/netbox/issues/792) - Add power port and power outlet types
 * [#1865](https://github.com/digitalocean/netbox/issues/1865) - Add console port and console server port types
 * [#2902](https://github.com/digitalocean/netbox/issues/2902) - Replace `supervisord` with `systemd`

+ 2 - 21
netbox/utilities/templatetags/buttons.py

@@ -2,6 +2,7 @@ from django import template
 from django.urls import reverse
 
 from extras.models import ExportTemplate
+from utilities.utils import prepare_cloned_fields
 
 register = template.Library()
 
@@ -24,27 +25,7 @@ def import_button(url):
 def clone_button(url, instance):
 
     url = reverse(url)
-
-    # Populate form field values
-    params = {}
-    for field_name in getattr(instance, 'clone_fields', []):
-        field = instance._meta.get_field(field_name)
-        field_value = field.value_from_object(instance)
-
-        # Swap out False with URL-friendly value
-        if field_value is False:
-            field_value = ''
-
-        # Omit empty values
-        if field_value not in (None, ''):
-            params[field_name] = field_value
-
-        # Copy tags
-        if hasattr(instance, 'tags'):
-            params['tags'] = ','.join([t.name for t in instance.tags.all()])
-
-    # Append parameters to URL
-    param_string = '&'.join(['{}={}'.format(k, v) for k, v in params.items()])
+    param_string = prepare_cloned_fields(instance)
     if param_string:
         url = '{}?{}'.format(url, param_string)
 

+ 30 - 0
netbox/utilities/utils.py

@@ -180,3 +180,33 @@ def to_meters(length, unit):
         return length * 0.3048
     if unit == CableLengthUnitChoices.UNIT_INCH:
         return length * 0.3048 * 12
+
+
+def prepare_cloned_fields(instance):
+    """
+    Compile an object's `clone_fields` list into a string of URL query parameters. Tags are automatically cloned where
+    applicable.
+    """
+    params = {}
+    for field_name in getattr(instance, 'clone_fields', []):
+        field = instance._meta.get_field(field_name)
+        field_value = field.value_from_object(instance)
+
+        # Swap out False with URL-friendly value
+        if field_value is False:
+            field_value = ''
+
+        # Omit empty values
+        if field_value not in (None, ''):
+            params[field_name] = field_value
+
+        # Copy tags
+        if hasattr(instance, 'tags'):
+            params['tags'] = ','.join([t.name for t in instance.tags.all()])
+
+    # Concatenate parameters into a URL query string
+    param_string = '&'.join(
+        ['{}={}'.format(k, v) for k, v in params.items()]
+    )
+
+    return param_string

+ 7 - 3
netbox/utilities/views.py

@@ -1,6 +1,4 @@
-import json
 import sys
-import yaml
 from copy import deepcopy
 
 from django.conf import settings
@@ -28,7 +26,7 @@ from extras.models import CustomField, CustomFieldValue, ExportTemplate
 from extras.querysets import CustomFieldQueryset
 from utilities.exceptions import AbortTransaction
 from utilities.forms import BootstrapMixin, CSVDataField
-from utilities.utils import csv_format
+from utilities.utils import csv_format, prepare_cloned_fields
 from .error_handlers import handle_protectederror
 from .forms import ConfirmationForm, ImportForm
 from .paginator import EnhancedPaginator
@@ -238,6 +236,12 @@ class ObjectEditView(GetReturnURLMixin, View):
             messages.success(request, mark_safe(msg))
 
             if '_addanother' in request.POST:
+
+                # If the object has clone_fields, pre-populate a new instance of the form
+                if hasattr(obj, 'clone_fields'):
+                    url = '{}?{}'.format(request.path, prepare_cloned_fields(obj))
+                    return redirect(url)
+
                 return redirect(request.get_full_path())
 
             return_url = form.cleaned_data.get('return_url')