Fixes #2414: Tags field missing from device/VM component creation forms

This commit is contained in:
Jeremy Stretch 2018-09-28 16:26:08 -04:00
parent 020b5ea870
commit 15babeb584
6 changed files with 16 additions and 21 deletions

View File

@ -9,6 +9,7 @@ v2.4.5 (FUTURE)
## Bug Fixes ## Bug Fixes
* [#2406](https://github.com/digitalocean/netbox/issues/2406) - Remove hard-coded limit of 1000 objects from API-populated form fields * [#2406](https://github.com/digitalocean/netbox/issues/2406) - Remove hard-coded limit of 1000 objects from API-populated form fields
* [#2414](https://github.com/digitalocean/netbox/issues/2414) - Tags field missing from device/VM component creation forms
* [#2442](https://github.com/digitalocean/netbox/issues/2442) - Nullify "next" link in API when limit=0 is passed * [#2442](https://github.com/digitalocean/netbox/issues/2442) - Nullify "next" link in API when limit=0 is passed
* [#2443](https://github.com/digitalocean/netbox/issues/2443) - Enforce JSON object format when creating config contexts * [#2443](https://github.com/digitalocean/netbox/issues/2443) - Enforce JSON object format when creating config contexts
* [#2444](https://github.com/digitalocean/netbox/issues/2444) - Improve validation of interface MAC addresses * [#2444](https://github.com/digitalocean/netbox/issues/2444) - Improve validation of interface MAC addresses

View File

@ -1194,6 +1194,7 @@ class ConsolePortForm(BootstrapMixin, forms.ModelForm):
class ConsolePortCreateForm(ComponentForm): class ConsolePortCreateForm(ComponentForm):
name_pattern = ExpandableNameField(label='Name') name_pattern = ExpandableNameField(label='Name')
tags = TagField(required=False)
class ConsoleConnectionCSVForm(forms.ModelForm): class ConsoleConnectionCSVForm(forms.ModelForm):
@ -1364,6 +1365,7 @@ class ConsoleServerPortForm(BootstrapMixin, forms.ModelForm):
class ConsoleServerPortCreateForm(ComponentForm): class ConsoleServerPortCreateForm(ComponentForm):
name_pattern = ExpandableNameField(label='Name') name_pattern = ExpandableNameField(label='Name')
tags = TagField(required=False)
class ConsoleServerPortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.Form): class ConsoleServerPortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.Form):
@ -1461,6 +1463,7 @@ class PowerPortForm(BootstrapMixin, forms.ModelForm):
class PowerPortCreateForm(ComponentForm): class PowerPortCreateForm(ComponentForm):
name_pattern = ExpandableNameField(label='Name') name_pattern = ExpandableNameField(label='Name')
tags = TagField(required=False)
class PowerConnectionCSVForm(forms.ModelForm): class PowerConnectionCSVForm(forms.ModelForm):
@ -1631,6 +1634,7 @@ class PowerOutletForm(BootstrapMixin, forms.ModelForm):
class PowerOutletCreateForm(ComponentForm): class PowerOutletCreateForm(ComponentForm):
name_pattern = ExpandableNameField(label='Name') name_pattern = ExpandableNameField(label='Name')
tags = TagField(required=False)
class PowerOutletConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.Form): class PowerOutletConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.Form):
@ -1864,6 +1868,7 @@ class InterfaceCreateForm(ComponentForm, forms.Form):
) )
description = forms.CharField(max_length=100, required=False) description = forms.CharField(max_length=100, required=False)
mode = forms.ChoiceField(choices=add_blank_choice(IFACE_MODE_CHOICES), required=False) mode = forms.ChoiceField(choices=add_blank_choice(IFACE_MODE_CHOICES), required=False)
tags = TagField(required=False)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -2101,6 +2106,7 @@ class DeviceBayForm(BootstrapMixin, forms.ModelForm):
class DeviceBayCreateForm(ComponentForm): class DeviceBayCreateForm(ComponentForm):
name_pattern = ExpandableNameField(label='Name') name_pattern = ExpandableNameField(label='Name')
tags = TagField(required=False)
class PopulateDeviceBayForm(BootstrapMixin, forms.Form): class PopulateDeviceBayForm(BootstrapMixin, forms.Form):

View File

@ -14,11 +14,6 @@
{% render_field form.mgmt_only %} {% render_field form.mgmt_only %}
{% render_field form.description %} {% render_field form.description %}
{% render_field form.mode %} {% render_field form.mode %}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>Tags</strong></div>
<div class="panel-body">
{% render_field form.tags %} {% render_field form.tags %}
</div> </div>
</div> </div>

View File

@ -11,6 +11,7 @@
{% render_field form.mtu %} {% render_field form.mtu %}
{% render_field form.description %} {% render_field form.description %}
{% render_field form.mode %} {% render_field form.mode %}
{% render_field form.tags %}
</div> </div>
</div> </div>
{% if obj.mode %} {% if obj.mode %}

View File

@ -710,24 +710,14 @@ class ComponentCreateView(View):
if form.is_valid(): if form.is_valid():
new_components = [] new_components = []
data = deepcopy(form.cleaned_data) data = deepcopy(request.POST)
data[self.parent_field] = parent.pk
for name in form.cleaned_data['name_pattern']: for name in form.cleaned_data['name_pattern']:
# Initialize data for the individual component form # Initialize the individual component form
component_data = { data['name'] = name
self.parent_field: parent.pk, component_form = self.model_form(data)
'name': name,
}
# Replace objects with their primary key to keep component_form.clean() happy
for k, v in data.items():
if hasattr(v, 'pk'):
component_data[k] = v.pk
else:
component_data[k] = v
component_form = self.model_form(component_data)
if component_form.is_valid(): if component_form.is_valid():
new_components.append(component_form) new_components.append(component_form)

View File

@ -419,11 +419,12 @@ class VirtualMachineFilterForm(BootstrapMixin, CustomFieldFilterForm):
# #
class InterfaceForm(BootstrapMixin, forms.ModelForm): class InterfaceForm(BootstrapMixin, forms.ModelForm):
tags = TagField(required=False)
class Meta: class Meta:
model = Interface model = Interface
fields = [ fields = [
'virtual_machine', 'name', 'form_factor', 'enabled', 'mac_address', 'mtu', 'description', 'mode', 'virtual_machine', 'name', 'form_factor', 'enabled', 'mac_address', 'mtu', 'description', 'mode', 'tags',
'untagged_vlan', 'tagged_vlans', 'untagged_vlan', 'tagged_vlans',
] ]
widgets = { widgets = {
@ -462,6 +463,7 @@ class InterfaceCreateForm(ComponentForm):
mtu = forms.IntegerField(required=False, min_value=1, max_value=32767, label='MTU') mtu = forms.IntegerField(required=False, min_value=1, max_value=32767, label='MTU')
mac_address = forms.CharField(required=False, label='MAC Address') mac_address = forms.CharField(required=False, label='MAC Address')
description = forms.CharField(max_length=100, required=False) description = forms.CharField(max_length=100, required=False)
tags = TagField(required=False)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):