kobayashi 6 лет назад
Родитель
Сommit
9694bacb69

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

@@ -26,6 +26,7 @@
 * [#3721](https://github.com/netbox-community/netbox/issues/3721) - Allow Unicode characters in tag slugs
 * [#3923](https://github.com/netbox-community/netbox/issues/3923) - Indicate validation failure when using SSH-style RSA keys
 * [#3951](https://github.com/netbox-community/netbox/issues/3951) - Fix exception in webhook worker due to missing constant
+* [#3950](https://github.com/netbox-community/netbox/issues/3950) - Fix "Create and Add Another" not keep Manufacturer and Device Type after device creation
 * [#3953](https://github.com/netbox-community/netbox/issues/3953) - Fix validation error when creating child devices
 * [#3960](https://github.com/netbox-community/netbox/issues/3960) - Fix legacy device status choice
 * [#3962](https://github.com/netbox-community/netbox/issues/3962) - Fix display of unnamed devices in rack elevations

+ 1 - 0
netbox/dcim/forms.py

@@ -1636,6 +1636,7 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldForm):
         instance = kwargs.get('instance')
         if 'initial' not in kwargs:
             kwargs['initial'] = {}
+
         # Using hasattr() instead of "is not None" to avoid RelatedObjectDoesNotExist on required field
         if instance and hasattr(instance, 'device_type'):
             kwargs['initial']['manufacturer'] = instance.device_type.manufacturer

+ 1 - 1
netbox/dcim/models/__init__.py

@@ -1409,7 +1409,7 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
         'site', 'rack_group', 'rack_name', 'position', 'face', 'comments',
     ]
     clone_fields = [
-        'device_type', 'device_role', 'tenant', 'platform', 'site', 'rack', 'status', 'cluster',
+        'device_type', 'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'site', 'rack', 'status', 'cluster', 'cluster__group',
     ]
 
     STATUS_CLASS_MAP = {

+ 19 - 3
netbox/utilities/utils.py

@@ -181,15 +181,31 @@ def render_jinja2(template_code, context):
     return Environment().from_string(source=template_code).render(**context)
 
 
+def get_field_value(instance, field_name):
+    """
+    Retrieve appropriate field name & value from object recursively.
+    """
+    if '__' in field_name:
+        fn = field_name.split('__')
+        attr = getattr(instance, fn[0])
+        return get_field_value(attr, fn[1])
+
+    field = instance._meta.get_field(field_name) if instance else None
+    field_value = field.value_from_object(instance) if field else None
+
+    if field_name == 'group':
+        field_name = 'cluster_group'
+    return field_name, field_value
+
+
 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)
+    for field in getattr(instance, 'clone_fields', []):
+        field_name, field_value = get_field_value(instance, field)
 
         # Swap out False with URL-friendly value
         if field_value is False: