From 790aed268882baaf8ff06242a475177da06de2cb Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 10 Dec 2024 15:36:59 -0500 Subject: [PATCH] Closes #18045: Enable adding a new MAC to an interface via quick add --- netbox/dcim/forms/common.py | 8 ------- netbox/dcim/forms/model_forms.py | 7 +++++++ netbox/utilities/forms/fields/dynamic.py | 21 +++++++++++++------ netbox/utilities/forms/widgets/apiselect.py | 9 ++++++++ .../templates/widgets/apiselect.html | 4 ++-- netbox/virtualization/forms/model_forms.py | 9 +++++++- 6 files changed, 41 insertions(+), 17 deletions(-) diff --git a/netbox/dcim/forms/common.py b/netbox/dcim/forms/common.py index 65d0d0f23..8ca258f34 100644 --- a/netbox/dcim/forms/common.py +++ b/netbox/dcim/forms/common.py @@ -3,9 +3,7 @@ from django.utils.translation import gettext_lazy as _ from dcim.choices import * from dcim.constants import * -from dcim.models import MACAddress from utilities.forms import get_field_value -from utilities.forms.fields import DynamicModelChoiceField __all__ = ( 'InterfaceCommonForm', @@ -20,12 +18,6 @@ class InterfaceCommonForm(forms.Form): max_value=INTERFACE_MTU_MAX, label=_('MTU') ) - primary_mac_address = DynamicModelChoiceField( - queryset=MACAddress.objects.all(), - label=_('Primary MAC address'), - required=False, - quick_add=True - ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py index d6fdb21e2..9bc69e991 100644 --- a/netbox/dcim/forms/model_forms.py +++ b/netbox/dcim/forms/model_forms.py @@ -1410,6 +1410,13 @@ class InterfaceForm(InterfaceCommonForm, ModularDeviceComponentForm): required=False, label=_('VRF') ) + primary_mac_address = DynamicModelChoiceField( + queryset=MACAddress.objects.all(), + label=_('Primary MAC address'), + required=False, + quick_add=True, + quick_add_params={'interface': '$pk'} + ) wwn = forms.CharField( empty_value=None, required=False, diff --git a/netbox/utilities/forms/fields/dynamic.py b/netbox/utilities/forms/fields/dynamic.py index 13d5ffc70..3eb49c1bd 100644 --- a/netbox/utilities/forms/fields/dynamic.py +++ b/netbox/utilities/forms/fields/dynamic.py @@ -93,6 +93,7 @@ class DynamicModelChoiceMixin: context=None, selector=False, quick_add=False, + quick_add_params=None, **kwargs ): self.model = queryset.model @@ -103,6 +104,7 @@ class DynamicModelChoiceMixin: self.context = context or {} self.selector = selector self.quick_add = quick_add + self.quick_add_params = quick_add_params or {} super().__init__(queryset, **kwargs) @@ -125,12 +127,6 @@ class DynamicModelChoiceMixin: if self.selector: attrs['selector'] = self.model._meta.label_lower - # Include quick add? - if self.quick_add: - app_label = self.model._meta.app_label - model_name = self.model._meta.model_name - attrs['quick_add'] = reverse_lazy(f'{app_label}:{model_name}_add') - return attrs def get_bound_field(self, form, field_name): @@ -171,6 +167,19 @@ class DynamicModelChoiceMixin: viewname = get_viewname(self.queryset.model, action='list', rest_api=True) widget.attrs['data-url'] = reverse(viewname) + # Include quick add? + if self.quick_add: + app_label = self.model._meta.app_label + model_name = self.model._meta.model_name + widget.quick_add_context = { + 'url': reverse_lazy(f'{app_label}:{model_name}_add'), + 'params': {}, + } + for k, v in self.quick_add_params.items(): + if v == '$pk': + v = form.instance.pk + widget.quick_add_context['params'][k] = v + return bound_field diff --git a/netbox/utilities/forms/widgets/apiselect.py b/netbox/utilities/forms/widgets/apiselect.py index 278371de6..f6db6f65c 100644 --- a/netbox/utilities/forms/widgets/apiselect.py +++ b/netbox/utilities/forms/widgets/apiselect.py @@ -22,6 +22,15 @@ class APISelect(forms.Select): dynamic_params: Dict[str, str] static_params: Dict[str, List[str]] + def get_context(self, name, value, attrs): + context = super().get_context(name, value, attrs) + + # Add quick-add context data, if set on the widget + if hasattr(self, 'quick_add_context'): + context['quick_add'] = self.quick_add_context + + return context + def __init__(self, api_url=None, full=False, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/netbox/utilities/templates/widgets/apiselect.html b/netbox/utilities/templates/widgets/apiselect.html index 51ee79e6a..2d5c9e493 100644 --- a/netbox/utilities/templates/widgets/apiselect.html +++ b/netbox/utilities/templates/widgets/apiselect.html @@ -15,7 +15,7 @@ {% endif %} - {% if widget.attrs.quick_add and not widget.attrs.disabled %} + {% if quick_add and not widget.attrs.disabled %} {# Opens the quick add modal #}